OK6410移植LINUX

移植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

  1. 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

  1. 製作根文件系統
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章