移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤###8. u-boot引导启动nand flash中内核和根文件系统cramfs和用户文件系统yaffs2支持

时间:2021-05-30 16:44:47

作者:reille

本博客网址:http://blog.csdn.net/reille/

开发环境:主机:Window XP SP2;linux:VMware7.01+ubuntu9.10;目标板:扬创utu2440-F开发板

交叉编译器:arm-linux-gcc4.3.2(一开始用的是编译内核的版本arm-linux-gcc3.4.1,但出现了软浮点问题,于是换成了现在用的版本,从本文章开始,内核编译也改用该交叉编译器)

移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤文章系列详细描述了本人移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤,同时把移植过程中遇到的问题及其解决方法记录了下来,以供参考步骤

本节详细描述:u-boot引导启动nand flash中内核和根文件系统cramfs和用户文件系统yaffs2支持

——————————————————————————————————————————————————————

1. u-boot引导启动NAND FLASH中内核

在上篇中,u-boot可以支持从NAND FLASH启动了,但这时还不能引导内核启动。另外,还注意到,u-boot从NAND FLASH启动时会提示

"NAND_ECC_NONE selected by board driver“,如下所示:

U-Boot 2011.03 (Jun 26 2011 - 02:40:58)

DRAM:  64 MiB

NAND:  NAND_ECC_NONE selected by board driver. This is not recommended !!

64 MiB

*** Warning - bad CRC, using default environment

In:    serial

Out:   serial

Err:   serial

Net:   CS8900-0

[reille2440]# 

这个问题暂不处理

1.1 修改和设置u-boot环境参数

u-boot环境参数可以在u-boot源码中设置,也可以在烧录到NAND FLASH后重新设置。

1.1.1 在u-boot源码中设定默认的环境参数,修改文件u-boot-2011.03/include/configs/reille2440.h

#define CONFIG_BOOTDELAY3
/*#define CONFIG_BOOTARGS"root=ramfs devfs=mount console=ttySA0,9600" */
/*#define CONFIG_ETHADDR08:00:3e:26:0a:5b ethaddr=00:0c:20:02:0a:5b */
#define CONFIG_ETHADDR00:0c:20:02:0a:5b
#define CONFIG_NETMASK255.255.255.0
#define CONFIG_IPADDR192.168.1.168
#define CONFIG_SERVERIP192.168.1.125
/*#define CONFIG_BOOTFILE"elinos-lart" */
/*#define CONFIG_BOOTCOMMAND"tftp; bootm" */

/***************added by guoyirong 2011.06.19**************/
#define CONFIG_SETUP_MEMORY_TAGS 1 // 如果没有定义这个参数,则uboot参数必须加入men=内存大小
#define CONFIG_INITRD_TAG 1
#define CONFIG_CMDLINE_TAG 1 // 设置bootargs出入内核必须

// nand flash boot |added by guoyirong 2011.07.02
#define CONFIG_BOOTARGS \
"root=/dev/mtdblock2 console=ttySAC0,115200 rootfstype=cramfs noinitrd mem=64M"

// boot default |added by guoyirong 2011.07.02
#define CONFIG_BOOTCOMMAND\
"nand read 0x30008000 0x60000 0x200000;bootm 0x30008000"

1.1.2 修改文件env_common,在default_environment[]中添加如下信息:

// added by guoyirong 2011.07.08"install-uboot=" "tftp 30000000 u-boot.bin;\nand erase 0 60000;nand write 30000000 0 60000" "\0""install-kernel=" "tftp 30000000 uImage;nand erase 60000 200000;\nand write 30000000 60000 200000" "\0""install-filesystem=" "tftp 30000000 rootfs.cramfs;nand erase 260000 300000;\nand write.jffs2 30000000 260000 300000" "\0""erase-env=" "nand erase 40000 20000" "\0"
在u-boot中分别运行run install-uboot、run install-kernel、run install-filesystem来烧写u-boot、kernel(uImage)、文件系统的镜像到NAND FLASH中,使镜像文件的烧写更加方便。

环境参数如下: [reille2440]# print
baudrate=115200
bootargs=root=/dev/mtdblock2 console=ttySAC0,115200 rootfstype=cramfs noinitrd mem=64M
bootcmd=nand read 0x30008000 0x60000 0x200000;bootm 0x30008000
bootdelay=3
ethact=CS8900-0
ethaddr=00:0c:20:02:0a:5b
ipaddr=192.168.1.168
netmask=255.255.255.0
serverip=192.168.1.125
stderr=serial
stdin=serial
stdout=serial

1.2 内核引导

环境参数正确之后,就可以正确引导NAND FLASH的内核镜像

2. 文件系统

选用只读的cramfs作为根文件系统,而用户文件系统采用yaffs2

cramfs是压缩的只读根文件系统,u-boot直接支持。

而像yaffs/yaffs2,则是未压缩的可读可写的文件系统,如果用作根文件系统,u-boot需要修改之后才能支持。

2.1 NAND FLASH分区

NAND FLASH分区信息如下: Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x000000000000-0x000000060000 : "uboot"
0x000000060000-0x000000260000 : "kernel"
0x000000260000-0x000000560000 : "rootfs"
0x000000560000-0x000004000000 : "user"
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver

开始的时候,由于粗心大意,分区有点错误,启动时出现如下信息:

mtd: partition "user" extends beyond the end of device "NAND 64MiB 3,3V 8-bit" -- size truncated to 0x3ba0000

意思是说,我的第4个分区超过了最大大小。

上面分区中,rootfs表示根文件系统分区,包括了动态链接库、命令程序等;user是用户文件系统分区,要运行的程序、数据都是放在此分区上

2.2 制作根文件系统

本来是想通过移植busybox1.16.0来制作一个.cramfs的根文件系统,移植busybox1.16.0没问题,编译通过,但是建立的根文件系统,用NFS挂载的时候出现如下问题:

Freeing init memory: 104K

Kernel panic - not syncing: Attempted to kill init!

Backtrace: 

[<c0026908>] (dump_backtrace+0x0/0x12c) from [<c0026a4c>] (dump_stack+0x18/0x1c)

 r7:c381c000 r6:c381a000 r5:c039793c r4:00000004

[<c0026a34>] (dump_stack+0x0/0x1c) from [<c0033b6c>] (panic+0x40/0x118)

[<c0033b2c>] (panic+0x0/0x118) from [<c0036338>] (do_exit+0x1bc/0x670)

 r3:c03728f4 r2:60000013 r1:c0375730 r0:c031a688

[<c003617c>] (do_exit+0x0/0x670) from [<c00368b8>] (do_group_exit+0x94/0xc0)

[<c0036824>] (do_group_exit+0x0/0xc0) from [<c0040558>] (get_signal_to_deliver+0x278/0x364)

 r4:00000004

[<c00402e0>] (get_signal_to_deliver+0x0/0x364) from [<c0025658>] (do_signal+0x5c/0x4b4)

[<c00255fc>] (do_signal+0x0/0x4b4) from [<c0025c70>] (do_notify_resume+0x2c/0x30)

[<c0025c44>] (do_notify_resume+0x0/0x30) from [<c0022e6c>] (work_pending+0x1c/0x20)

不管busybox采用动态库,还是采用静态管;也不管是用交叉编译器arm-linux-gcc-3.4.1还是arm-linux-gcc-4.3.2,即使内核中配置了EABI选项,问题找不到解决方法,因此后面放弃,改为用现成的根文件系统和用户文件系统。

这个问题,我估计是文件系统相关配置不正确导致的

2.3 制作CRAMFS根文件系统镜像

制作前,建议先用NFS挂载自己的根文件系统检测其是否可行,如果NFS可成功挂载,则说明你的根文件系统没问题了。

制作CRAMFS根文件镜像需要工具mkcramfs,我采用的是现成的且为静态编译mkcramfs工具,可直接使用

mkcramfs rootfs rootfs.cramfs
其中,rootfs 是根文件系统目录,rootfs.cramfs即生成的cramfs根文件系统镜像文件

生成后,在u-boot中把根文件系统镜像烧写到NAND FLASH对应的分区中。nand write.jffs2命令是u-boot本身自带中。

tftp 30000000 rootfs.cramfs;nand erase 260000 300000;nand write.jffs2 30000000 260000 300000

2.4 烧录CRAMFS文件系统镜像文件后出现错误

用mkcramfs工具生成了.cramfs镜像文件,同时烧写到NAND FLASH相应分区中。但启动时出现了如下错误:

rivers/rtc/hctosys.c: unable to open rtc device (rtc0)

uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2, sector 0

Buffer I/O error on device mtdblock2, logical block 0

uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2, sector 0

Buffer I/O error on device mtdblock2, logical block 0

end_request: I/O error, dev mtdblock2, sector 8

Buffer I/O error on device mtdblock2, logical block 1

end_request: I/O error, dev mtdblock2, sector 8

Buffer I/O error on device mtdblock2, logical block 1

uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2, sector 16

Buffer I/O error on device mtdblock2, logical block 2

uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2, sector 16

Buffer I/O error on device mtdblock2, logical block 2

uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2, sector 24

Buffer I/O error on device mtdblock2, logical block 3

uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2, sector 24

Buffer I/O error on device mtdblock2, logical block 3

uncorrectable error : <3>uncorrectable error : <3>end_request: I/O error, dev mtdblock2, sector 0

FAT: unable to read boot sector

VFS: Cannot open root device "mtdblock2" or unknown-block(31,2)

Please append a correct "root=" boot option; here are the available partitions:

1f00             384 mtdblock0 (driver?)

1f01            2048 mtdblock1 (driver?)

1f02            2048 mtdblock2 (driver?)

1f03           61056 mtdblock3 (driver?)

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)

Backtrace: 

[<c0026908>] (dump_backtrace+0x0/0x12c) from [<c0026a4c>] (dump_stack+0x18/0x1c)

 r7:c3809000 r6:c001e8d0 r5:c03958fc r4:c3809007

[<c0026a34>] (dump_stack+0x0/0x1c) from [<c0033b6c>] (panic+0x40/0x118)

[<c0033b2c>] (panic+0x0/0x118) from [<c0008d78>] (mount_block_root+0xfc/0x24c)

 r3:00000000 r2:20000013 r1:c381df54 r0:c0315f3c

[<c0008c7c>] (mount_block_root+0x0/0x24c) from [<c0008f94>] (mount_root+0xcc/0xec)

[<c0008ec8>] (mount_root+0x0/0xec) from [<c00090ac>] (prepare_namespace+0xf8/0x194)

 r6:c03952c4 r5:c001e888 r4:c001e88c

[<c0008fb4>] (prepare_namespace+0x0/0x194) from [<c0008a2c>] (kernel_init+0xc8/0xf4)

 r6:c001d44c r5:c001d0fc r4:c03952b8

[<c0008964>] (kernel_init+0x0/0xf4) from [<c003617c>] (do_exit+0x0/0x670)

 r6:00000000 r5:00000000 r4:00000000

开始以为是u-boot的启动参数不对所致,但改来改去,终是这个错误。后面在网上找到了解决方法,原因不是u-boot的启动参数导致的,而是自己移植的linux内核中NAND FLASH的ECC所致。
本人移植的内核版本是linux-2.6.30.4,修改内核文件:drivers/mtd/nand/s3c2410.c

在s3c2410_nand_init_chip()函数中,把

chip->ecc.mode    = NAND_ECC_SOFT;

改为

chip->ecc.mode    = NAND_ECC_NONE;

重新编译内核并下载到NAND FLASH则可以正常挂载NAND FLASH中的cramfs根文件系统了。

2.5 用户文件系统

用户文件系统位于NAND FLASH的mtdblock3分区中,采用适用于NAND FLASH的yaffs2格式文件系统。 当根文件系统挂载成功后,在相应启动脚本中把mtdblock3分区挂载到/mnt目录中。这样,当linux和文件系统启来后,文件系统中的mnt目录则我们的用户文件系统了。 到这里,或许有个疑问,用户文件系统是怎么烧写到的NAND FLASH的mtdblock3分区中呢? 其实这个问题很简单,也有多种方法。 1) 根文件系统启来后,用FTP把用户文件系统直接上传到mnt目录即可     当然,第一次使用之前,需要把mnt目录“格式化”一下,即先擦除一次mtdblock3分区。 2) 把用户文件系统打包,放在根文件系统某目录中如usr目录中,当根文件系统启动并挂载mtdblock3分区后,检测mnt目录下是否有标志文件,如果没有,则先擦除mtdblock3分区,再把用户文件系统解压到mnt目录中,同时在mnt目录中建立标志文件,防止以后每次启动根文件系统时都执行这样的操作。 本人采用了第二种方式,同时用户文件系统采用了高压缩率的7z格式。 宿主机安装7z命令方法:
sudo apt-get install p7zip-full

安装之后有7z7za两个命令,7za是一个独立的命令,支持的格式比7z

把用户文件系统用7z打包后,放在usr相关目录中,同时在根文件系统中建立相应的执行脚本,脚本如何实现,在此不放出来了!

3. 附记:使用交换机实现目标板和开发PC互联互通

在此之前,曾使用过路由器来实现目标板和开发PC(宿主机)互联互通,但宿主机不能上外网了,仍旧是要上网查资料时,要把目标板跟宿主机的网线拔掉,插上外网线。 不过,这次挺好,终于不用这么麻烦了,使用TPLINK交换机实现了

4. 参考资料

4.1 制作CRAMFS文件系统镜像文件:

http://blog.ednchina.com/xiong_gang_whut/240012/message.aspx

4.2 烧录CRAMFS文件系统镜像文件后出现错误:

http://blog.163.com/jant126@126/blog/static/12008366200791110249642/ 

http://blog.21ic.com/user1/1831/archives/2010/70196.html

http://blog.csdn.net/hfyinsdu/article/details/5953364

http://www.cnblogs.com/yyangblog/archive/2011/06/14/2080773.html

4.3 根文件系统制作:

http://blog.csdn.net/csuwzc/article/details/6527654