移植linux-3.7.3
#mkimage工具
製作LINUX內核的壓縮鏡像文件,需要用到mkimage工具,在uboot的tools目錄下,mkimage可以用來製作壓縮/不壓縮的多種內核鏡像文件。如果uboot/tools中沒有mkimage,可以嘗試apt安裝 sudo apt-cache search mkimage
Usage: mkimage -l image
-l ==> list image header information
mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
-x ==> set XIP (execute in place)
解壓linux內核源代碼
export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
改上面這段代碼的arch = arm和cross_compile = arm-linux-
準備
cp arch/arm/mach-s3c64xx/mach-mini6410.c arch/arm/mach-s3c64xx/mach-ok6410.c
#替換其中 mini6410 MINI6410
arch/arm/mach-s3c64xx/Makefile:
# Machine support
obj-$(CONFIG_MACH_OK6410) += mach-ok6410.o
#Kconfig
Kconfig用來描述所屬目錄源文檔相關的內核配置菜單
arch/arm/mach-s3c64xx/Kconfig:
# S3C6410 machine support
config MACH_OK6410
bool "OK6410"
select CPU_S3C6410
select SAMSUNG_DEV_ADC
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_I2C1
select SAMSUNG_DEV_IDE
select S3C_DEV_FB
select S3C_DEV_RTC
select SAMSUNG_DEV_TS
select S3C_DEV_USB_HOST
select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select S3C64XX_SETUP_SDHCI
select S3C64XX_SETUP_I2C1
select S3C64XX_SETUP_IDE
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD
help
Machine support for the OK6410
添加之後執行make menuconfig就會有ok6410選項
添加ID
arch/arm/tools/mach-types:
ok6410 MACH_OK6410 OK6410 1626
回到linux根目錄執行make menuconfig
如果報錯 apt-get install libncurses* (提供字符中斷處理)
爲了使make xconfig不出錯 build-essential kernel-package libqt3-headers libqt3-mt-dev
->Load an Alternate Configuration File 輸出配置文件的路徑arch/arm/configs中s3c6400_defconfig最接近ok6410
->General Setup
->Cross-compiler tool prefix 交叉工具鏈的路徑
/home/forlinx/tools/arm-linux-gcc/bin/arm-linux-
->System Type
(0) S3C UART to use for low-level message
[*]OK6410
->Save an Alternate Configuration File
.config
此時在.config文件中可以看到配置信息
make uImage
在arch/arm/boot 下生成uImage zImage兩種內核鏡像
將uImage放入SD卡即可引導內核
內核啓動地址entryadd
內核鏡像加載地址loadadd fatload mmc 0 50008000 uImage
內核鏡像入bootmadd bootm 50008000
1)如果loadadd == bootmadd ,bootm不會對uImage header後的zImage進行memory move的動作
而會直接go到entry point執行, 因此此時的entry point 必須爲 loadadd + 0x40
如果kernel boot過程沒有到uncompressing the kernel,就可能是設置不對
bootmadd == loadadd == entryadd - 0x40
2)如果loadadd != bootmadd , 需要避免memory move時因爲覆蓋導致zImage被破壞的情況
此時bootm會把uImage header後的zImage文件move到loadadd , 然後go到entry point開始執行
這段代碼在common/cmd_bootm.c中的bootm_load_os函數中,此時loadadd 必須等於 entry point
bootmadd != loadadd == entryadd
linux/script/Makefile.lib:
修改入口點地址
UIMAGE_LOADADDR ?= arch_must_set_this
#UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
UIMAGE_ENTRYADDR ?= $(shell echo $(UIMAGE_LOADADDR) | sed -e "s/..$$/40/")
MTD分區
MTD(Memory Technology Device 內存技術設備)是linux系統中快閃存儲器轉換層
arch/arm/mach-s3c6x–/mach-ok6410.c
static struct mtd_partition ok6410_nand_part[] = {
[0] = {
.name = "uboot",
.size = SZ_1M,
.offset = 0,
},
[1] = {
.name = "kernel",
.size = SZ_2M,
.offset = SZ_1M,
},
[2] = {
.name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = SZ_1M + SZ_2M,
},
};
>>>
static struct mtd_partition ok6410_nand_part[] = {
[0] = {
.name = "Bootloader",
.size = (1*SZ_1M),
.offset = 0,
.mask_flags = MTD_CAP_NANDFLASH,
},
[1] = {
.name = "Kernel",
.size = (5*SZ_1M),
.offset = (1*SZ_1M),
.mask_flags = MTD_CAP_NANDFLASH,
},
[2] = {
.name = "File System",
.size = (200*SZ_1M),
.offset = (6*SZ_1M),
},
[3] = {
.name = "User",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
},
};
make uImage
添加NAND驅動
將s3c_nand.c放入/dirvers/mtd/nand/
nand.h -> /arch/arm/plat-samsung/include/plat/
/dirvers/mtd/nand/Makefile:
obj-$(CONFIG_MTD_NAND_S3C) += s3c_nand.o #任意位置
添加menuconfig選項
/drivers/mtd/nand/Kconfig:
config MTD_NAND_S3C2410後添加
config MTD_NAND_S3C
tristate "NAND Flash support for Samsung S3C SoCs"
depends on (ARCH_S5P64XX || ARCH_S3C64XX || ARCH_S5PC1XX) && MTD_NAND
help
This enables the NAND flash controller on the S3C2.
No board specific support is done by this driver, each board
must advertise a platform_device for the driver to attach.
config MTD_NAND_S3C_DEBUG
bool "S3C NAND driver debug"
depends on MTD_NAND_S3C
help
Enable debugging of the S3C NAND driver
config MTD_NAND_S3C_HWECC
bool "S3C NAND Hardware ECC"
depends on MTD_NAND_S3C
help
Enable the use of the controller's internal ECC generator when
using NAND. Early versions of the chips have had problems with
incorrect ECC generation, and if using these, the default of
software ECC is preferable.
添加s3c_nand.c文件中的寄存器
arch/arm/plat-samsung/include/plat/regs-nand.h:
#if 1
#define S3C_NFCONF S3C2410_NFREG(0X00)
#define S3C_NFCONT S3C2410_NFREG(0x04)
#define S3C_NFCMMD S3C2410_NFREG(0X08)
#define S3C_NFADDR S3C2410_NFREG(0X0C)
#define S3C_NFDATA8 S3C2410_NFREG(0X10)
#define S3C_NFDATA S3C2410_NFREG(0X10)
#define S3C_NFMECCDATA0 S3C2410_NFREG(0X14)
#define S3C_NFMECCDATA1 S3C2410_NFREG(0X18)
#define S3C_NFSECCDATA S3C2410_NFREG(0x1c)
#define S3C_NFSBLK S3C2410_NFREG(0X20)
#define S3C_NFEBLK S3C2410_NFREG(0X24)
#define S3C_NFSTAT S3C2410_NFREG(0X28)
#define S3C_NFMECCERR0 S3C2410_NFREG(0X2C)
#define S3C_NFMECCERR1 S3C2410_NFREG(0X30)
#define S3C_NFMECC0 S3C2410_NFREG(0X34)
#define S3C_NFMECC1 S3C2410_NFREG(0X38)
#define S3C_NFSECC S3C2410_NFREG(0X3C)
#define S3C_NFMLCBITPT S3C2410_NFREG(0X40)
#define S3C_NF8ECCERR0 S3C2410_NFREG(0X44)
#define S3C_NF8ECCERR1 S3C2410_NFREG(0X48)
#define S3C_NF8ECCERR2 S3C2410_NFREG(0X4C)
#define S3C_NFM8ECC0 S3C2410_NFREG(0X50)
#define S3C_NFM8ECC1 S3C2410_NFREG(0X54)
#define S3C_NFM8ECC2 S3C2410_NFREG(0X58)
#define S3C_NFM8ECC3 S3C2410_NFREG(0X5C)
#define S3C_NFMLC8BITPT0 S3C2410_NFREG(0X60)
#define S3C_NFMLC8BITPT1 S3C2410_NFREG(0X64)
#define S3C_NFCONF_NANDBOOT (1<<31)
#define S3C_NFCONF_ECCCLKCON (1<<30)
#define S3C_NFCONF_ECC_MLC (1<<24)
#define S3C_NFCONF_ECC_1BIT (0<<23)
#define S3C_NFCONF_ECC_4BIT (2<<23)
#define S3C_NFCONF_ECC_8BIT (1<<23)
#define S3C_NFCONF_TACLS(x) ((x)<<12)
#define S3C_NFCONF_TWRPH0(x) ((x)<<8)
#define S3C_NFCONF_TWRPH1(x) ((x)<<4)
#define S3C_NFCONF_ADVFLASH (1<<3)
#define S3C_NFCONF_PAGESIZE (1<<2)
#define S3C_NFCONF_ADDRCYCLE (1<<1)
#define S3C_NFCONF_BUSWIDTH (1<<0)
#define S3C_NFCONT_ECC_ENC (1<<18)
#define S3C_NFCONT_LOCKTGHT (1<<17)
#define S3C_NFCONT_LOCKSOFT (1<<16)
#define S3C_NFCONT_8BITSTOP (1<<11)
#define S3C_NFCONT_MECCLOCK (1<<7)
#define S3C_NFCONT_SECCLOCK (1<<6)
#define S3C_NFCONT_INITMECC (1<<5)
#define S3C_NFCONT_INITSECC (1<<4)
#define S3C_NFCONT_nFCE1 (1<<2)
#define S3C_NFCONT_nFCE0 (1<<1)
#define S3C_NFCONT_INITECC (S3C_NFCONT_INITSECC | S3C_NFCONT_INITMECC)
#define S3C_NFSTAT_ECCENCDONE (1<<7)
#define S3C_NFSTAT_ECCDECDONE (1<<6)
#define S3C_NFSTAT_BUSY (1<<0)
#define S3C_NFECCERR0_ECCBUSY (1<<31)
#endif
修改ecclayout結構
/drivers/mtd/nand/nand_base.c:
static struct nand_ecclayout nand_oob_218 = {
.eccbytes = 104,
.eccpos = {
24,25,26,27,28,29,30,31,32,33,
34,35,36,37,38,39,40,41,42,43,
44,45,46,47,48,49,50,51,52,53,
54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,
74,75,76,77,78,79,80,81,82,83,
84,85,86,87,88,89,90,91,92,93,
94,95,96,97,98,99,100,101,102,103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127},
.oobfree = {
{.offset = 2,
.length = 22} }
};
nand_scan_tail()
{
...
case 218:
chip->ecc.layout = &nand_oob_218;
break;
....//如果NAND的分區沒有提示,必須註釋下面的BUG();
if (mtd->writesize >= chip->ecc.size) {
if (!chip->ecc.strength) {
pr_warn("Driver must set ecc.strength when using hardware ECC\n");
//BUG();
}
break;
}
s3c_nand.c:
nand_scan_probe(){
nand->ecc.layout = &s3c_nand_oob_mlc_218_8bit;
}
添加NAND初始化
/arch/arm/mach-s3c64xx/mach-ok6410.c:
ok6410_machine_init()
{
...
s3c_device_nand.name = "s3c6410-nand";
//這三行前
s3c_nand_set_platdata(&ok6410_nand_info);
s3c_fb_set_platdata(&ok6410_lcd_pdata[features.lcd_index]);
s3c24xx_ts_set_platdata(NULL);
}
make menuconfig
->Device Drivers
-->Memory Technology Device (MTD) support
--->NAND Device Support
< >NAND Flash support for Samsung S3C SoCs
<*>NAND Flash support for S3C SoC
[*]S3C NAND driver debug
[*]S3C NAND Hardware ECC
配置完成 make uImage
添加DM9000網卡驅動
在menuconfig中添加即可
YAFFS2根文件系統
git clone git://www.aleph1.co.uk/yaffs2
mv yaffs2 linux/
給內核打補丁,添加yaffs2文件系統
.yaffs2/patch-ker.sh c m /home/forlinx/linux/linux-3.7.3
出現fs/yaffs2/說明打補丁成功
linux/fs/yaffs2/yaffs_vfs.c:
#if (YAFFS_NEW_XATTR>0)
static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode,
make menuconfig
->Device Drivers
-->[*]Memory Technology Device (MTD) support
<*> Caching block device access to MTD devices
->File systems
-->[*]Miscellaneous filesystems
<*> yaffs2 file system support
配置完成後 make uImage
製作根文件系統
工具 mkyaffs2image /yaffs2/utils BusyBox
- mkyaffs2image製作
/yaffs2/utils/mkyaffs2image.c:
// Adjust these to match your NAND LAYOUT:
#define chunkSize 2048
#define spareSize 64
#define pagesPerBlock 64
>>
// Adjust these to match your NAND LAYOUT:
#define chunkSize 4096
#define spareSize 218
#define pagesPerBlock 128
/yaffs2/direct/yportenv.h
+++
#define CONFIG_YAFFS_DEFINES_TYPES
/yaffs2/utils目錄下編譯生成mkyaffs2image工具
make
- 製作根文件系統
tar -jxvf busybox-1.20.2.tar.bz2
buysbox-1.20.2/Makefile :
CROSS_COMPILE ?= /home/forlinx/tools/arm-linux-gcc/bin/arm-linux-
ARCH ?= ARM
配置busybox
make menuconfig
-> Busybox setting
--> build Option
()Cross Compiler prefix
/home/forlinx/tools/arm-linux-gcc/bin/arm-linux-
-> Busybox setting
--> General Configuration
[*] Don`t use /usr
完成後編譯 make 生成 busybox 文件
安裝busybox, make install 生成 _install 文件夾,此時有 bin sbin linuxrc目錄 chmod 777 linuxrc
爲了使根文件系統正常運行,還需要添加其他目錄,在_install下編寫腳本
busybox-1.20.2/_intall/create_yaffs2.sh:
#!/bin/bash
echo "+++++ Ronny +++++"
echo "+++++ busybox sh +++++"
echo "+++++ Create yaffs2 other ... +++++"
mkdir root dev etc bin sbin mnt sys proc lib home tmp var usr
mkdir usr/sbin usr/bin usr/lib usr/modules usr/etc
mkdir mnt/usb mnt/nfs mnt/etc mnt/etc/init.d
mkdir etc/init.d
mkdir lib/modules
chmod 777 tmp
sudo mknod -m 600 dev/console c 5 1
sudo mknod -m 666 dev/null c 1 3
#sudo mknod -m 666 dev/led c 240 0 #240-主設備號 0-次設備號
echo "+++++ Created +++++"
執行腳本生成
添加必要的文件
etc/profile : 爲系統設定環境變量
# Ash profile
# vim: syntax=sh
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
USER="'id -un'"
LOGNAME=$USER
PS1='[\u@\h \W]\# '
PATH=$PATH
HOSTNAME='/bin/hostname'
export USER LOGNAME PS1 PATH
etc/fstab : 指明當執行mount -a時,需要掛接的文件系統
proc /proc proc defaults 0 0
none /tmp ramfs defaults 0 0
none /var ramfs defaults 0 0
mdev /dev ramfs defaults 0 0
sysfs /sys sysfs defaults 0 0
etc/inittab : init進程的配置文件
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
::shutdown:/bin umount -a -r
::shutdown:/sbin/swapoff -a
etc/init.d/rcS : 並給它最大權限 chmod 777 rcS
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
trap ":" INT QUIT TSTP
/bin/hostname ok6410 #hostname set , or use default
/bin/mount -n -t proc none /proc
/bin/mount -n -t sysfs none /sys
mkdir -R /proc/bus/usb #added
/bin/mount -n -t usbfs none /proc/bus/usb
/bin/mount -t ramfs none /dev
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
/bin/hotplug
#mounting file system specified in /etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
/bin/mount -n -t devpts none /dev/pts -o mode=0622
/bin/mount -n -t tmpfs tmpfs /dev/shm
/bin/mount -n -t ramfs none /tmp
/bin/mount -n -t ramfs none /var
mkdir -p /var/empty
mkdir -p /var/log
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/tmp
/sbin/hwclock -s -f /dev/rtc
syslogd
/etc/rc.d/init.d/netd start
echo " " > /dev/tty1
echo "Starting networking..." > /dev/tty1
echo "******************************"
echo "Welcome to Ronny root!"
echo " "
echo "Name : Ronny "
echo "E-mali : [email protected]"
echo "******************************"
mkdir /mnt/disk
mount -t yaffs2 /dev/mtdblock3 /mnt/disk
mount -t vfat /dev/mmcblk0p1 /home/
mount -t yaffs2 /dev/mtdblock3 /mnt/
cd /mnt/
tar zxvf /home/urbetter-rootfs-qt-2.2.0.tgz
sync
cd /
umount /mnt/
umount /home/
/sbin/ifconfig 1o 127.0.0.1
chmod +x etc/init.d/ifconfig-eth0
/etc/init.d/ifconfig-eth0
/bin/qtopia &
echo " " > /dev/tty1
echo "Starting Qtopia, please waiting..." > /dev/tty1
echo " "
echo "Staring Qtopia, please waiting..."
usr/etc/init : chmod 777 init
#!/bin/sh
ifconfig eth0 192.168.1.0 up
ifconfig 1o 127.0.0.1
usr/etc/mdev.conf : 空
將arm-linux-gcc/libc/lib/下所有so庫文件複製到lib/
sudo cp ~/tools/arm-linux-gcc/libexec/gcc/arm-unknown-linux-gnueabi/4.7.2/*so* lib/
busybox-1.20.2/目錄下使用mkyaffs2image _install rootfs.yaffs2
../linux-3.7.3/yaffs2/utils/mkyaffs2image _install/ rootfs.yaffs2
配置內核make menuconfig
->Device Drivers
-->Gneric Drivers Options
[*] Maintain a devtmpfs filesystem to mount at /dev
[*] Automount devtmpfs at /dev, after the kernel mounted...
->File System
< > Second extended fs support
< > Ext3 journalling file system support
--> <*> Miscellaneous filesystem
<*> BeOS file system (BeFs) support(read only) (EXPERIMENTAL)
[ ] Debug BeFs
->Boot Option
輸入啓動參數
noinitrd root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200
配置完成後編譯內核make uImage,將生成的內核和文件系統一起燒入開發板
燒寫yaffs到nand
通過
arch/arm/mach-s3c6x--/mach-ok6410.c :
static struct mtd_partition ok6410_nand_part[] = {
[0] = {
.name = "Bootloader",
.size = (1*SZ_1M),
.offset = 0,
.mask_flags = MTD_CAP_NANDFLASH,
},
[1] = {
.name = "Kernel",
.size = (5*SZ_1M),
.offset = (1*SZ_1M),
.mask_flags = MTD_CAP_NANDFLASH,
},
[2] = {
.name = "File System",
.size = (200*SZ_1M),
.offset = (6*SZ_1M),
},
[3] = {
.name = "User",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
},
};
我們知道,yaffs放在NAND OFFSET=6*1024 (0x0060_0000) SIZE=200*1024 (0x0C80_0000)
Uboot配置
uboot/include/configs/ok6410.h
#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200"
//這個的作用是傳遞給內核的啓動參數,啓動設備爲mtd的2區,yaffs2文件系統,也可以在內核配置中更改
#ifdef CONFIG_BOOT_SD
#define CONFIG_BOOTCOMMAND "fatload mmc 0 50008000 u-boot-nand.bin;" \
"nand erase.chip;" \
"nand write.uboot 50008000 0 0"
#else
#define CONFIG_BOOTCOMMAND "fatload mmc 0 50008000 rootfs.yaffs2;" \
"nand erase 600000 c800000;" \
"nand write.yaffs 50008000 600000 d2a5000;" \
"fatload mmc 0 50008000 uImage;" \
"bootm 50008000"
#endif
//0xda25000 = 0xc800000 + (0xc800000/0x100000)*218
uboot/drivers/mtd/nand_util.c
nand_write_skip_bad()
{
...
printf("#");
left_to_write -= write_size;
}
printf("\n");
return 0;
}
uboot/driver/mtd/nand/nand_util.c
if (!need_skip && !(flags & WITH_DROP_FFS)&& !(flags & WITH_YAFFS_OOB)) {
//if (!need_skip && !(flags & WITH_DROP_FFS)) {
將uboot重新編譯,把yaffs2文件系統燒進nand中,啓動內核
[debug recording]
bug: 有大量ECC uncorrected error be detected,屏蔽ecc校驗
uboot linux yaffs2 三者的oob佈局要保持一致,ecc校驗方式/位數要保持一致
yaffs2會佔用oob的24個字節
bug:
devtmpfs mounted
Kernel panic - not syncing: No init found. Try passing init= option
說明文件系統已經掛載成功,但沒有找到init,需要看init指定文件是否存在,權限問題,動態鏈接庫是否存在
或者將busybox編譯成靜態庫
busybox中
make menuconfig
->Busybox Setting
-->Build Options
[*]Build BusyBox as a static binary(no shared libs)
make
make install
再次編譯yaffs2文件系統
../linux-3.7.3/yaffs2/utils/mkyaffs2image _install rootfs.yaffs2
將編譯好的yaffs2寫入nand即可啓動
bug: devtmpfs error mounting: -2
取消kernel config
Device Driver
General Driver Option
Maintain a devtmpfs ...
bug:
devtmpfs mounted
Failed to execute /linuxrc. Attempting defaults...
說明文件系統已經掛載成功,但沒有找到init,需要看init指定文件是否存在,權限問題,動態鏈接庫是否存在
bug:
yaffs_vfs.c :
#if (YAFFS_NEW_XATTR>0)
static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode,
LCD顯示驅動
OK6410標配LCD型號爲WXCAT43,4.3寸電阻觸摸屏,分辨率爲480*272
arch/arm/mach-s3c64xx/mach-ok6410.c :
static struct s3c_fb_pd_win ok6410_lcd_type0_fb_win = {
.max_bpp = 32,
.default_bpp = 16,
.xres = 480,
.yres = 272,
};
static struct fb_videomode ok6410_lcd_type0_timing = {
//.pixclock //像素時鐘
/* 4.3" 480x272 */
.left_margin = 3, //行切換,從同步到繪圖之間的延時 HBP
.right_margin = 2, //行切換,從繪圖到同步之間的延時 HFP
.upper_margin = 1, //幀切換,從同步到繪圖之間的延時 VBP
.lower_margin = 1, //幀切換,從繪圖到同步之間的延時 VFP
.hsync_len = 40, //水平同步的長度 HSPW
.vsync_len = 1, //垂直同步的長度 VSPW
.xres = 480,
.yres = 272,
};
>>>
static struct s3c_fb_pd_win ok6410_lcd_type0_fb_win = {
.max_bpp = 32,
.default_bpp = 16,
.xres = 480,
.yres = 272,
};
static struct fb_videomode ok6410_lcd_type0_timing = {
/* 4.3" 480x272 */
.left_margin = 3,
.right_margin = 5,
.upper_margin = 3,
.lower_margin = 3,
.hsync_len = 42,
.vsync_len = 120,
.xres = 480,
.yres = 272,
};
+++
static struct map_desc ok6410_iodesc[] = {
{
.virtual = (unsigned long)S3C_VA_LCD,
.pfn = __phys_to_pfn(S3C_PA_FB),
.length = SZ_16K,
.type = MT_DEVICE,
},
};
arch/arm/plat-samsung/include/plat/map-base.h:
+++ #define S3C_VA_LCD S3C_ADDR(0X01100000)
arch/arm/mach-s3c64xx/mach-ok6410.c :
ok6410_map_io()
{
...
//s3c64xx_init_io(NULL, 0);
s3c64xx_init_io(ok6410_iodesc,ARRAY_SIZE(ok6410_iodesc));
...
}
mkdir dirvers/video/samsung
ls drivers/video/samsung
built-in.c s3cfb_fimd4x.c s3cfb.c s3cfb_VGA800.c s3cfb_WXCAT43.c Kconfig
s3cfb_AT070.c s3cfb_AT050.c s3cfb_spi.c s3cfb_WXCAT35.c s3cfb_XGA1024.c
s3cfb_AT056.c s3cfb.h
mv regs-lcd.h arch/arm/mach-s3c64xx/include/mach/
mv regs-fb.h arch/arm/mach-s3c64xx/include/mach/
mv regs-fb-v4.h arch/arm/plat-samsung/include/plat/
mv regs-fb.h arch/arm/plat-samsung/include/plat/
drivers/video/Kconfig
+++ source "drivers/video/samsung/Kconfig"
drivers/video/Makefile
+++ obj-$(CONFIG_FB_S3C_EXT) += samsung/
如果編譯提示s3c6410_pm_do_save s3c6410_pm_do_restore 函數隱式聲明
drivers/video/samsung/s3cfb_fimd4x.c
int s3cfb_suspend()
{
...
#if 0
s3c6410_pd_do_save();
#endif
...
}
int s3cfb_resume()
{
...
#if 0
s3c6410_pm_do_restore();
#endif
...
}
修改完成,配置內核
->Devicee Drivers
-->Graphics support
<*>Support for frame buffer devices
< >Samsung S3C framebuffer support
<*>S3C Framebuffer Support (eXtended)
Select LCD Type(4.3 inch 480X272 TFT LCD)
(x)4.3 inch 480X272 TFT LCD
<*>Advanced options for S3C Framebuffer
Select BPP(Bits Per Pixel)(16 BPP)
(X)16 BPP
[*]Enable Double Buffering
->Console display driver support
<*>Framebuffer Console support
[]Map the console to the primary display device
LCD幾種常見問題:
(1)刷新頻率不正常
現象:屏幕像流動瀑布一樣有明顯向下刷新的光條。
原因:LCD的時鐘頻率設置不對
(2)整體顏色出現反色
現象:原本應該爲紅色卻變成藍色,藍色變成紅色
原因:RGB數據排列錯誤
(3)圖像整體水平偏移
現象:LCD畫面整體左右偏移,與下一個圖像之間出現一個黑色豎條紋
原因:行同步信號的時序參數不對,需要調整
(4)圖像整體上下偏移
現象:LCD畫面整體上下偏移,與下一個圖像之間出現一個黑色橫條紋
原因:幀同步信號的時序參數不對,需要調整
(5)圖像只顯示在上半部分
現象:LCD畫面只顯示上半部分
原因:顯示緩衝區長度設置錯誤
(6)顯示緩衝區數據錯誤
現象:LCD屏幕出現隨機的豎條紋
原因:顯示緩衝區是亂碼,或者顯存數據沒有及時更新
LCD觸摸屏驅動
arch/arm/mach-s3c64xx/mach-ok6410.c
+++ #include <mach/dev-ts.h>
+++ static struct s3c_ts_mach_info s3c_ts_platform __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
.resol_bit = 12,
.s3c_adc_con = ADC_TYPE_2,
};
+++ staci void __init ok6410_machine_init(void)
{
...
#if 0
s3c24xx_ts_set_platdata(NULL);
#endif
s3c_ts_set_platdata(&s3c_ts_platform);
...
}
mv dev-ts.c arch/arm/mach-s3c64xx
arch/arm/mach-s3c64xx/dev-ts.c
+++ #include <linux/gfp.h>
mv dev-ts.h arch/arm/mach-s3c64xx/include/mach
arhc/arm/mach-s3c64xx/include/mach/dev-ts.h
+++ #include <linux/module.h>
arch/arm/mach-s3c64xx/Makefile
+++ obj-$(CONFIG_TOUCHSCREEN_S3C) += dev-ts.o
mv s3c-ts.c drivers/input/touchscreen/
drivers/input/touchscreen/Makefile
+++ obj-$(CONFIG_TOUCHSCREEN_S3C) += s3c-ts.o
drivers/input/touchscreen/s3c-ts.c:
+++
#define S3C_ADCREG(x) (x)
#define S3C_ADCCON S3C_ADCREG(0x00)
#define S3C_ADCTSC S3C_ADCREG(0x04)
#define S3C_ADCDLY S3C_ADCREG(0x08)
#define S3C_ADCDAT0 S3C_ADCREG(0x0C)
#define S3C_ADCDAT1 S3C_ADCREG(0x10)
#define S3C_ADCUPDN S3C_ADCREG(0x14)
#define S3C_ADCCLRINT S3C_ADCREG(0x18)
#define S3C_ADCMUX S3C_ADCREG(0x1C)
#define S3C_ADCCLRWK S3C_ADCREG(0x20)
// ADCCON Register Bits
#define S3C_ADCCON_RESSEL_10BIT (0x0<<16)
#define S3C_ADCCON_RESSEL_12BIT (0x1<<16)
#define S3C_ADCCON_ECFLG (1<<15)
#define S3C_ADCCON_PRSCEN (1<<14)
#define S3C_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
#define S3C_ADCCON_PRSCVLMASK (0xFF<<6)
#define S3C_ADCCON_SELMUX(x) (((x)&0x7)<<3)
#define S3C_ADCCON_SELMUX_1(x) (((x)&0xF)<<0)
#define S3C_ADCCON_MUXMASK (0x7<<3)
#define S3C_ADCCON_RESSEL_10BIT_1 (0x0<<3)
#define S3C_ADCCON_RESSEL_12BIT_1 (0x1<<3)
#define S3C_ADCCON_STDBM (1<<2)
#define S3C_ADCCON_READ_START (1<<1)
#define S3C_ADCCON_ENABLE_START (1<<0)
#define S3C_ADCCON_STARTMASK (0x3<<0)
// ADCTSC Register Bits
#define S3C_ADCTSC_UD_SEN (1<<8)
#define S3C_ADCTSC_YM_SEN (1<<7)
#define S3C_ADCTSC_YP_SEN (1<<6)
#define S3C_ADCTSC_XM_SEN (1<<5)
#define S3C_ADCTSC_XP_SEN (1<<4)
#define S3C_ADCTSC_PULL_UP_DISABLE (1<<3)
#define S3C_ADCTSC_AUTO_PST (1<<2)
#define S3C_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
// ADCDAT0 Bits
#define S3C_ADCDAT0_UPDOWN (1<<15)
#define S3C_ADCDAT0_AUTO_PST (1<<14)
#define S3C_ADCDAT0_XY_PST (0x3<<12)
#define S3C_ADCDAT0_XPDATA_MASK (0x03FF)
#define S3C_ADCDAT0_XPDATA_MASK_12BIT (0x0FFF)
// ADCDAT1 Bits
#define S3C_ADCDAT1_UPDOWN (1<<15)
#define S3C_ADCDAT1_AUTO_PST (1<<14)
#define S3C_ADCDAT1_XY_PST (0x3<<12)
#define S3C_ADCDAT1_YPDATA_MASK (0x03FF)
#define S3C_ADCDAT1_YPDATA_MASK_12BIT (0x0FFF)
include/linux/interrupt.h
+++ #define IRQF_SAMPLE_RANDOM 0x00000040
drviers/input/touchscreen/Kconfig
+++
config TOUCHSCREEN_S3C
tristate "S3C touchscreen driver"
depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5P64XX || ARCH_S5PC1XX
default y
help
Say Y here to enable the driver for the touchscreen on the S3C SMDK board.
If unsure, say N
to compile this drivers as a module, choose M here: the module will be called s3c_ts.
配置內核
->Device Drivers
-->Input device support
[*]Touchscreens
<*>S3C touchscreen driver
->System Type
[*]ADC common driver support
->Device Drivers
-->Input device support
<*>Evnet interface
如果出現多重定義錯誤
arch/arm/plat-samsung/devs.c
--- s3c_device_ts
#內核裁剪
General setup
(ok6410) Default hostname
[] Initial RAM filesystem
Device Drivers
<> I2C support
[] SPI support
<> HSI support
<> Hardware Monitoring support
<> Sound card support
[] USB support
<> MMC/SD/SDIO card support
File System
-> Miscellaneous filesystems
<> BeOS file system(BeFS) support
Kernel Configuration
-> Library routines
<*>XZ decompression support
[] x86 BCJ filter decoder
[] PowerPC BCJ filter decoder
[] IA-64 BCJ filter decoder
[*] ARM BCJ filter decoder
[*] ARM-Thumb BCJ filter decoder
[] SPARC BCJ filter decoder