移植环境
1,主机环境:VMare下CentOS 5.5 ,1G内存。
2,集成开发环境:Elipse IDE
3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-eabi-gcc v4.5.1。
4,开发板:mini2440,2M nor flash,128M nand flash。
5,u-boot版本:u-boot-2009.08
6,参考文章:
6.1,u-boot配置
【1】机器码的确定
通常,在u-boot和kernel中都会有一个机器码(即:MACH_TYPE),只有这两个机器码一致时才能引导内核,否则就会出现如下mach的错误信息或者死机。
打开board/samsung/mini2440/mini2440.c,定位到124行附近,修改如下:
#if defined(CONFIG_S3C2410)
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
#endif
#if defined(CONFIG_S3C2440)
/* arch number of S3C2440-Board */
gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif
对于u-boot-2009.08来说,MACH_TYPE_MINI2440已经在include/asm-arm/mach-types.h 文件的1985行附件有定义。
#define MACH_TYPE_Q2440 1997
#define MACH_TYPE_QQ2440 1998
#define MACH_TYPE_MINI2440 1999 //mini2440的机器码
#define MACH_TYPE_COLIBRI300 2000
#define MACH_TYPE_JADES 2001
【2】修改u-boot中内核引导参数:
打开/include/configs/mini2440.h,定位到60行附近,修改如下:
#define CONFIG_BOOTDELAY 3
#define CONFIG_SETUP_MEMORY_TAGS 1 //如果没有定义这个参数,则uboot参数必须加入men=内存大小
#define CONFIG_INITRD_TAG 1
#define CONFIG_CMDLINE_TAG 1 //设置bootargs出入内核必须
#define CONFIG_BOOTARGS "noinitrd console=ttySAC0,115200 init=/linuxrc \
root=/dev/mtdblock3 rw rootfstype=yaffs \
ip=10.1.0.129:10.1.0.128:10.1.0.1:255.255.255.0::eth0:off"
/* "noinitrd console=ttySAC0,115200 init=/linuxrc mem=64M \
root=/dev/nfs rw nfsroot=10.1.0.128:/nfsboot \
ip=10.1.0.129:10.1.128:10.1.0.1:255.255.255.0::eth0:off"
*/
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 10.1.0.129
#define CONFIG_SERVERIP 10.1.0.128
#define CONFIG_GATEWAYIP 10.1.0.1
#define CONFIG_OVERWRITE_ETHADDR_ONCE
/*#define CONFIG_BOOTFILE "elinos-lart" */
#define CONFIG_BOOTCOMMAND "nand read 0x30008000 0x80000 0x300000;bootm 0x30008000"
/*"nfs 0x30008000 10.1.0.128:/nfsboot/zImage.img;bootm" */
#define CONFIG_EXTRA_ENV_SETTINGS \
"singleboy=bmp d 70000\0 " \
"stdin=serial\0" \
"stdout=serial\0" \
"stderr=serial\0" \
""
#if defined(CONFIG_CMD_KGDB)
bootargs参数解析:
initrd, noinitrd: 当你没有使用ramdisk启动系统的时候,你需要使用noinitrd这个参数,但是如果使用了的话,就需要指定initrd=r_addr,size, r_addr表示initrd在内存中的位置,size表示initrd的大小。
console: console=tty 使用虚拟串口终端设备 。console=ttyS[,options] 使用特定的串口,options可以是这样的形式bbbbpnx,这里bbbb是指串口的波特率,p是奇偶位(从来没有看过使用过),n是指的bits。 console=ttySAC[,options] 同上面。看你当前的环境,有时用ttyS,有时用ttySAC,网上有人说,这是跟内核的版本有关,2.4用ttyS,2.6用ttySAC,但实际情况 是官方文档中也是使用ttyS,所以应该是跟内核版本没有关联的。可以查看Documentation/serial-console.txt找到相关描 述。
init: 指定的是内核启起来后,进入系统中运行的第一个脚本,一般init=/linuxrc, 或者init=/etc/preinit,preinit的内容一般是创建console,null设备节点,运行init程序,挂载一些文件系统等等操 作。请注意,很多初学者以为init=/linuxrc是固定写法,其实不然,/linuxrc指的是/目录下面的linuxrc脚本,一般是一个连接罢 了。如果内核找不到linurc文件,将会依搜索/sbin/init, /etc/init,/bin/init,/bin/sh.
mem: 指定内存大小,不是必须的。
root: 用来指定rootfs的位置, 常见的情况有:
root=/dev/ram rw
root=/dev/ram0 rw
请注意上面的这两种设置情况是通
用的,我做过测试甚至root=/dev/ram1 rw和root=/dev/ram2
rw也是可以的,网上有人说在某些情况下是不通用的,即必须设置成ram或者ram0,但是目前还没有遇到,还需要进一步确认,遇到不行的时候可以逐一尝
试。
root=/dev/mtdx rw
root=/dev/mtdblockx rw
root=/dev/mtdblock/x rw
root=31:0x
上面的这几个在一定情况下是通用的,当然这要看你当前的系统是否支持,不过mtd是字符设备,而mtdblock是块设备,有时候你的挨个的试到底 当前的系统支持上面那种情况下,不过root=/dev/mtdblockx rw比较通用。此外,如果直接指定设备名可以的话,那么使用此设备的设备号也是可以的。
root=/dev/nfs,并非真的设备,而是一个告诉内核经由网络取得根文件系统的旗标。
在文件系统为基于nfs的文件系统的时候使用。当然指定root=/dev/nfs之后,还需要指定nfsroot,这个参数告诉内核以哪一台机器,哪个目录以及哪个网络文件系统选项作为根文件系统使用。参数的格式如下:
nfsroot=[
如果指令列上没有给定 nfsroot 参数,则将使用‘/tftpboot/%s’预设值。其它选项如下:
port = as given by server portmap daemon
rsize = 1024
wsize = 1024
timeo = 7
retrans = 3
acregmin = 3
acregmax = 60
acdirmin = 30
acdirmax = 60
flags = hard, nointr, noposix, cto, ac
参数nfsaddrs设定网络通讯所需的各种网络接口地址。如果没有给定这个参数,则内核核会试着使用反向地址解析协议以及或是启动协议(BOOTP)以找出这些参数。下面是U-boot官方文档提供的IP参数解析,其格式如下:
setenv bootargs ${bootargs}
ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname:${netdev}:off
注意,上面换行的地方均有空格。其中 10.1.0.129是开发板的IP,10.1.0.128是PC端(或虚拟机)的IP,上面的IP根据自己的实际情况修改,不要弄错了。参数nfsaddrs格式如下:
nfsaddrs=
此参数可以作为 nfsaddrs 的参数单独使用(前面没有任何 `:` 字符),这种情况下会使用自动配置。然而,此种情况不能使用 `none'作为值。
保存修改。
重新编译下载后,nand方式启动。
【3】制作能被u-boot直接引导的内核uImage
通常,kernel的启动需要u-boot提供一些参数信息,比如ramdisk在
RAM中的地址。经过编译后的u-boot在根目录下的tools目录中,会有个叫做mkimage的工具,他可以给zImage添加一个header,
也就是说使得通常我们编译的内核zImage添加一个数据头信息部分,我们把添加头后的image通常叫uImage,uImage是可以被u-boot
直接引导的内核镜像。
mkimage工具的使用介绍如下:
使用: 中括号括起来的是可选的
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' //用于指定CPU类型,比如ARM
-O:set operating system to 'os' //用于指定操作系统,比如Linux
-T:set image type to 'type' //用于指定image类型,比如Kernel
-C:set compression type 'comp' //指定压缩类型
-a:set load address to 'addr' (hex) //指定image的载入地址
-e:set entry point to 'ep' (hex) //内核的入口地址,一般为image的载入地址+0x40(信息头的大小)
-n:set image name to 'name' //image在头结构中的命名
-d:use image data from 'datafile' //无头信息的image文件名
-x:set XIP (execute in place) //设置执行位置
先
将u-boot下的tools中的mkimage复制到主机的/usr/local/bin目录下,这样就可以在主机的任何目录下使用该工具了。现在我们
进入kernel生成目录(一般是arch/arm/boot目录),然后执行如下命令,就会在该目录下生成一个uImage.img的镜像文件,把他复
制到tftp目录下,这就是我们所说的uImage。打开终端,现操作如下:
[root@localhost ~]# cd /tftpboot
[root@localhost tftpboot]# ls
root_qtopia-128M.img zImage_T35
[root@localhost
tftpboot]# mkimage -n 'mini2440_linux' -A arm -O linux -T kernel -C
none -a 0x30008000 -e 0x30008040 -d zImage_T35 uImage_T35
Image Name: mini2440_linux
Created: Thu May 12 11:37:00 2011
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2022348 Bytes = 1974.95 kB = 1.93 MB
Load Address: 30008000
Entry Point: 30008040
[root@localhost tftpboot]#
更改用户执行权限
[root@localhost tftpboot]# ls -a
. .. root_qtopia-128M.img uImage_T35 zImage_T35
[root@localhost tftpboot]# ls -l
总计 61140
-rwxrw-rw- 1 root root 58487616 2009-07-18 root_qtopia-128M.img
-rw-r--r-- 1 root root 2022412 05-12 11:37 uImage_T35
-rwxrw-rw- 1 root root 2022348 2009-07-08 zImage_T35
[root@localhost tftpboot]# chmod a+x uImage_T35
[root@localhost tftpboot]# ls -l
总计 61140
-rwxrw-rw- 1 root root 58487616 2009-07-18 root_qtopia-128M.img
-rwxr-xr-x 1 root root 2022412 05-12 11:37 uImage_T35
-rwxrw-rw- 1 root root 2022348 2009-07-08 zImage_T35
[root@localhost tftpboot]#
(2)把uImage.img用tftp下载到内存中,然后再固化到Nand Flash中,操作如下:
[u-boot@MINI2440]# tftp 0x30000000 uImage_T35
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 10.1.0.128; our IP address is 10.1.0.129
Filename 'uImage_T35'.
Load address: 0x30000000
Loading: #################################################################
#################################################################
########
done
Bytes transferred = 2022412 (1edc0c hex)
[u-boot@MINI2440]#
用bootm命令启动:
[u-boot@MINI2440]# bootm 0x30008000
## Booting kernel from Legacy Image at 30008000 ...
Image Name: mini2440_linux
Created: 2011-05-12 3:37:00 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2022348 Bytes = 1.9 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux.............................................................
..................................................................... done, boot
ing the kernel.
Linux version 2.6.29.4-FriendlyARM (root@tom) (gcc version 4.3.2 (Sourcery G++ L
ite 2008q3-72) ) #3 Wed Jul 8 18:19:20 CST 2009
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=00007177
CPU: VIVT data cache, VIVT instruction cache
Machine: FriendlyARM Mini2440 development board
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
... ...
Try to bring eth0 interface up......eth0: link up, 100Mbps, full-duplex, lpa 0x4
5E1
Done
Please press Enter to activate this console.
-/bin/sh: id: not found
[root@FriendlyARM /]# ls
bin get linuxrc proc sdcard www
dev home lost+found root sys
etc lib opt sbin var
[root@FriendlyARM /]#
【4】设置u-boot引导参数并保存到nand flash
设置启动参数,意思是将nand中0x80000-0x300000(和kernel分区一致)的内容读到内存0x30008000中,然后用bootm命令来执行(如果在第一步中的mini2440.h文件设置是正确的,此步可以不做):
[u-boot@MINI2440]# set bootargs noinitrd root=/dev/mtdblock3 console=ttySAC0
[u-boot@MINI2440]# set bootcmd nand read 0x30008000 0x80000 300000 \; bootm 0x30008000
[u-boot@MINI2440]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x4000000000002 -- 0% complete.
Writing to Nand... done
[u-boot@MINI2440]#
【5】将内核写入Nand flash,系统上电后自引导:
擦除nand的0x80000-0x300000的内容,并将将内存0x30008000处的内容写入到nand的0x80000处:
[u-boot@MINI2440]# nand erase 0x80000 0x300000
NAND erase: device 0 offset 0x80000, size 0x300000
Erasing at 0x36000001800000 -- 0% complete.
OK
[u-boot@MINI2440]# nand write 30008000 0x80000 0x300000
NAND write: device 0 offset 0x80000, size 0x300000
Writing at 0x36000000020000 -- 100% is complete. 3145728 bytes written: OK
[u-boot@MINI2440]#
U-Boot 2009.08
modified by singleboy (singleboy@163.com)
Love Linux forever!!
DRAM: 64 MB
Flash: 2 MB
NAND: 128 MiB
Video: 240x320x16 20kHz 62Hz
In: serial
Out: serial
Err: serial
Net: dm9000
U-Boot 2009.08
modified by singleboy(singleboy@163.com)
Love Linux forever!!
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x80000, size 0x300000
3145728 bytes read: OK
## Booting kernel from Legacy Image at 30008000 ...
Image Name: mini2440_linux
Created: 2011-05-12 3:37:00 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2022348 Bytes = 1.9 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux.............................................................
..................................................................... done, boot
ing the kernel.
Linux version 2.6.29.4-FriendlyARM (root@tom) (gcc version 4.3.2 (Sourcery G++ L
ite 2008q3-72) ) #3 Wed Jul 8 18:19:20 CST 2009
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=00007177
CPU: VIVT data cache, VIVT instruction cache
Machine: FriendlyARM Mini2440 development board
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, (c) 2004 Simtec Electronics
S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: noinitrd root=/dev/mtdblock3 console=ttySAC0
... ...
mount: mounting none on /tmp failed: No such file or directory
hwclock: settimeofday() failed: Invalid argument
/etc/rc.d/init.d/netd: line 16: /usr/sbin/inetd: not found
/etc/rc.d/init.d/httpd: line 16: /usr/sbin/boa: not found
/etc/rc.d/init.d/leds: line 16: /usr/bin/led-player: not found
Try to bring eth0 interface up......eth0: link down
Done
Please press Enter to activate this console. eth0: link up, 100Mbps, full-duplex
, lpa 0x45E1
-/bin/sh: id: not found
[root@FriendlyARM /]# ls
bin get linuxrc proc sdcard www
dev home lost+found root sys
etc lib opt sbin var
[root@FriendlyARM /]#
内核和yaffs2文件系统成功引导起来了。