Linux2.6.24移植到utu2440
一、准备工作
安装libcurses5-dev,否则make menuconfig出错
# sudo apt-get install libcurses5-dev build-essential
下载Linux内核源码,大名鼎鼎源码网站http://www.kernel.org/pub/linux/kernel/v2.6
# cd /home/liao/image
# tar –zxvf linux2.6.24.tar.bz2
# cd linux-2.6.24
下载yaffs源码,http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/,与内核放在同一目录
二、移植修改内核源码
1. 匹配U-boot和kernel机器码,选择之一修改
uboot中机器码设置gd->bd->bi_arch_number = MACH_TYPE_S3C2440(362)。在文件u-boot/include/asm-arm/mach-types.h
内核机器码是由文件arch/arm/mach-s3c2440/mach-smdk2440.c中的函数
MACHINE_START(S3C2440, "SMDK2440")的第一个参数S3C2440决定的。linux内核中的机器码位于文件arch/arm/tools/mach-types查看文件中S3C2440机器码是362,但是后来将编译出的内核下载到开发板出现错误Error: unrecognized/unsupported machine ID,机器码一样却不能引导内核。由于我是在SDRAM采用go方式启动内核,这种方式不同于bootm方式,u-boot不会传machine ID给内核,go只是执行普通的应用程序。
参考网上blog:http://blog.csdn.net/dongliqiang2006/archive/2009/05/21/4207309.aspx
修改uboot中机器码为gd->bd->bi_arch_number = MACH_TYPE_SMDK2440(1008)。
修改内核中MACHINE_START(S3C2440, "SMDK2440")为MACHINE_START(SMDK2440, "SMDK2440")
修改arch/arm/kernel/head.S文件
.section ".text.head", "ax"
.type stext, %function
ENTRY(stext)
/*********add here***********/
mov r0,#0
mov r1,#0x3f0
ldr r2,=0x30000100
/*********add end***********/
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
这样修改以后的编译出的内核可以go引导。
2. 修改Makefile
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
3. 修改晶振频率arch/arm/mach-s3c2440/mach-smdk2440.c
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
4. 配置内核
先调用了默认的配置文件s3c2410_defconfig,在此基础上根据开发板配置内核
# make s3c2410_defconfig
# make menuconfig
5.配置内核,在上面一步调用默认配置文件,现在加上一些必要的配置
System Type --->
S3C2410 Machines --->
[*] SMDK2410/A9M2410 一定选上,其它N掉
S3C2440 Machines --->
[*] SMDK2440
[*] SMDK2440 with S3C2440 CPU module 留下这两项
S3C2400 Machines --->、S3C2412 Machines --->、S3C2442 Machines --->、S3C2443 Machines --->里面的选项全部N掉,有人说在2440中[*] SMDK2410/A9M2410可以不要,但是我试过会出错,不知道是不是版本问题。
arch/arm/plat-s3c24xx/s3c244x.c: In function `s3c244x_init_clocks':
arch/arm/plat-s3c24xx/s3c244x.c:121: error: implicit declaration of function `s3c2410_baseclk_add'
make[1]: *** [arch/arm/plat-s3c24xx/s3c244x.o] 错误 1
make: *** [arch/arm/plat-s3c24xx] 错误 2
Boot options --->
(root=/dev/hda1 ro init=/bin/bash console=ttySAC0)
改成(noinitrd root=/dev/mtdblock3 rootfstype=yaffs console=ttySAC0,115200 init=/linuxrc mem=64M)
nfs方式挂载根文件系统:noinitrd root=/dev/nfs rw nfsroot=192.168.1.128:/utu2440/rootfs ip=192.168.1.7:192.168.1.128:255.255.255.0 console=ttySAC0,115200 init=/linuxrc
Userspace binary formats --->
< > Kernel support for a.out and ECOFF binaries N掉此选项,
a.out和ECOFF是两种可执行文件的格式,在ARM-Linux下一般都用ELF
三、编译内核
# make zImage
# make modules
在arch/arm/boot目录中生成zImage,但是此时大部分硬件驱动未添加,也没用文件系统。Bootm可以直接引导uImage,2.6.27以后的内核可以直接用make uImage来生成uImage镜像,但是bootm引导zImage格式内核需要用U-boot的mkimage工具处理内核。因为在用bootm 命令引导内核的时候,bootm 需要读取一个64 字节的文件头,来获取这个内核映象所针对的CPU 体系结构、OS、加载到内存中的位置、在内存中入口点的位置以及映象名等等信息。这样bootm 才能为OS 设置好启动环境,并跳入内核映象的入口点。而mkimage 就是添加这个文件头的专用工具。
mkimage 工具的使用:
参数说明:
-A 指定 CPU 的体系结构,可用值有:alpha、arm 、x86、ia64、mips、mips64、
ppc 、s390、sh、sparc 、sparc64、m68k 等
-O 指定操作系统类型,可用值有:openbsd、netbsd、freebsd、4_4bsd、linux、
svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、
rtems、artos
-T 指定映象类型,可用值有:standalone、kernel、ramdisk、multi、firmware、script、
filesystem
-C 指定映象压缩方式,可用值有:
none 不压缩(一般使用这个,因为zImage 是已经被bzip2 压缩过的自解压内核)
gzip 用gzip 的压缩方式
bzip2 用bzip2 的压缩方式
-a 指定映象在内存中的加载地址,映象下载到内存中时,要按照用 mkimage 制作映象
时,这个参数所指定的地址值来下载
-e 指定映象运行的入口点地址,这个地址就是-a 参数指定的值加上0x40(因为前面有个
mkimage 添加的0x40 个字节的头)
-n 指定映象名
-d 指定制作映象的源文件
以下是制作内核映像的命令示例:
mkimage -A arm -O linux -T kernel -C none -a 0x30008000 –e 0x30008040 -n linux-2.6.24 -d zImage zImage.img
四、驱动移植
4.1 NAND Flash驱动移植
修改NAND Flash分区信息、硬件信息arch/arm/plat-s3c24xx/common-smdk.c
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "uboot",
.size = 0x00040000,
.offset = 0,
},
[1] = {
.name = "param",
.offset = 0x00040000,
.size = 0x00020000,
},
[2] = {
.name = "kernel",
.offset = 0x00060000,
.size = 0x00200000,
},
[3] = {
.name = "filesystem",
.offset = 0x002600000,
.size = 0x03d9c0000,
},
/*[4] = {
.name = "S3C2410 flash partition 4",
.offset = SZ_1M * 10,
.size = SZ_4M,
},
[5] = {
.name = "S3C2410 flash partition 5",
.offset = SZ_1M * 14,
.size = SZ_1M * 10,
},
[6] = {
.name = "S3C2410 flash partition 6",
.offset = SZ_1M * 24,
.size = SZ_1M * 24,
},
[7] = {
.name = "S3C2410 flash partition 7",
.offset = SZ_1M * 48,
.size = SZ_16M,
}*/
};
……
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 0,
.twrph0 = 30,
.twrph1 = 0,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
注意:不要按照以前一些移植内核在devs.c添加分区信息,不然启动时会有以下出错信息。
kobject_add failed for s3c2410-nand with -EEXIST, don't try to register things with the same name in the same directory.
[<c00290a8>] (dump_stack+0x0/0x14) from [<c0110a9c>] (kobject_shadow_add+0x160/0x1a8)
[<c011093c>] (kobject_shadow_add+0x0/0x1a8) from [<c0110af8>] (kobject_add+0x14/0x18)
[<c0110ae4>] (kobject_add+0x0/0x18) from [<c015117c>] (device_add+0xa0/0x568)
[<c01510dc>] (device_add+0x0/0x568) from [<c0155180>] (platform_device_add+0x100/0x150)
[<c0155080>] (platform_device_add+0x0/0x150) from [<c01551f0>]
去掉nand flash的ECC,drivers/mtd/nand/s3c2410.c
我的内核是通过U-BOOT写到Nand Flash的, U-BOOT通过的软件ECC算法产生ECC校验码, 这与内核校验的ECC码不一样, 内核中的ECC码是由S3C2410中Nand Flash控制器产生的。所以,我在这里选择禁止内核ECC校验。
在s3c2410_nand_init_chip()函数中
chip->ecc.mode=NAND_ECC_SOFT;
改成
chip->ecc.mode=NAND_ECC_NONE;
NAND Flash配置:
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
[*] MTD partitioning support
<*> RedBoot partition table parsing
[*] Command line partition table parsing
<*> NAND Device Support --->
<*> NAND Flash support for S3C2410/S3C2440 SoC
4.2 yaffs2文件系统
对于YAFFS文件系统,网上说没有必要移植YAFFS2,因为它是为每页大于1024B的NAND Flash设计的。其实即使移植了YAFFS2,如果你的NAND Flash是每页512+16B的那系统也会自动挂载YAFFS。
# tar –zxvf cvs-root.tar.gz
# cd cvs/yaffs2
# ./patch-ker.sh c /home/liao/image/linux-2.6.24
Yaffs配置:(同时加上了jffs2、cramfs、网络文件)
File systems -->
< > Second extended fs support N掉对ext2的支持
< > Ext3 journalling file system support N掉对ext3的支持
<*> Kernel automounter support 添加3项
<*> Kernel automounter version 4 support (also supports v3)
<*> Filesystem in Userspace support
Pseudo filesystems -->
[*] Virtual memory file system support (former shm fs) 添加2项
<*> Userspace-driven configuration filesystem (EXPERIMENTAL)
Miscellaneous filesystems -->
<*> YAFFS2 file system support 增加yaffs支持
[ ]Autoselect yaffs2 format 这两项是给每页大于1024B的NAND Flash
[ ]Cache short names in RAM
<*> Journalling Flash File System v2 (JFFS2) support 以下是对jffs支持
(0)JFFS2 debugging verbosity (0 = quiet, 2 = noisy)
[*]JFFS2 write-buffering support
[ ]Verify JFFS2 write-buffer reads
[ ]JFFS2 summary support (EXPERIMENTAL)
[ ]JFFS2 XATTR support (EXPERIMENTAL)
[*]Advanced compression options for JFFS2
[*]JFFS2 ZLIB compression support
[]JFFS2 LZO compression support
[*]JFFS2 RTIME compression support
[*]JFFS2 RUBIN compression support
Network File Systems -->
<*> NFS file system support
[*]Provide NFSv3 client support 这4项,否则挂载NFS可能出现protocol不支持
[*]Provide client support for the NFSv3 ACL protocol extension
[*]Provide NFSv4 client support (EXPERIMENTAL)
[*]Allow direct I/O on NFS files
<*> NFS server support
[*]Provide NFSv3 server support
[*]Provide server support for the NFSv3 ACL protocol extension
[*]Provide NFSv4 server support (EXPERIMENTAL)
-*-Provide NFS server over TCP support
[*]Root file system on NFS
-*- Native language support --->
--- Native language support
(iso8859-1) Default NLS Option
<*> Codepage 437 (United States, Canada)
<*> Simplified Chinese charset (CP936, GB2312)
<*> NLS ISO 8859-1 (Latin 1; Western European Languages)
<*> NLS UTF-8