SKYEYE上的
UCLINUX从主机NFS目录启动根文件系统
By HC 06/04/2006
经过一段时间艰苦的工作,我找到了一个可以让SKYEYE上的 UCLINUX从主机NFS目录启动根文件系统的方法。详细步骤如下:
首先,介绍一下我的软件环境:
主机操作系统:带有NFS服务的FEDORA CORE 1 或RED HAT 9
SKYEYE:0.8.0.0.
交叉编译器:arm-elf-tools-20030314.sh
UCLINUX; uClinux-dist-20030522.tar
根文件系统:./skyeye-binary-testutils-.0.7/at91/uclinux3/boot.rom
SKYEYE NET DRIVER: uclinux4skyeye-v0.2.3.tgz
经过多次的实验,我发现如果主机用2.6.X核心,在SKYEYE上的 uclinux不能正常使用NFS的client,这是我在主机上使用FEDORA CORE 1或RED HAT 9 的原因。而且,由于我发现SKYEYE0.8网络部分比1.0的要快,也没有经常出现发送超时的告警,所以我选择SKYEYE0.8。
1. 在主机上根据安装说明,解压或安装SKYEYE,SKYEYE—BINARY—TESTUTILES:SKYEYE网络驱动,交叉编译器和 UCLINUX。下面是一些简单的例子:
/* Install Skyeye0.8*/
#tar jxfv skyeye-0.8.0.tar.bz2
#./configure --target=arm-elf --prefix=/usr/local
#make
#make install
/* uncompress skyeye-binary-testutils */
#tar jxfv skyeye-binary-testutils-1.0.7.1.tar.bz2
/* Install a cross complier */
#sh arm-elf-tools-20030314.sh
/* uncompress uclinux resource code */
#tar zxf uClinux-dist-20030522.tar.gz
/* uncompress and install Skyeye net drivers */
#tar zxf uclinux4skyeye-v0.2.3.tgz
#cd uclinux4skyeye
#cp example/ uclinux-dist-20030522/vendor__GDB_ARMulator/* ../ uClinux-dist/vendors/GDB/ARMulator/
#cp example/ uclinux-dist-20030522/linux-2.4.x__drivers__net/* ../ uClinux-dist/drivers/net/
2 在主机建立 Uclinux根文件系统的NFS目录和配置NFS服务器;
2.1 将BOOT.IMG中根文件系统复制到一个NFS目录在主机上;
#mount -o loop boot.img /mnt/tmp /*加载根文件系统到一个临时目录 */
#cd /mnt/tmp
#cp . /tmp/nfs –r /* /tmp/nfs 将是 uclinux根文件系统的NFS目录 */
注意:为了避免启动冲突和节约启动时间,请删除下面这一行,
“/bin/ifconfig eth0 up 10.0.0.2” in /tmp/nfs/etc/rc.
2.2 在主机上配置NFS服务,然后重启服务器。
用菜单就可以完成:
System Settings->Server settings->NFS->Add button:
Directory: /tmp/nfs
Host(s): *
Basic permissions : Read/Write
System Settings->Server settings->Services->nfs(click mouse right button)->restart
3 修改 uclinux的相关原代码,使 uclinux可以从主机NFS目录启动根文件系统。一共有两个c语言文件的四个地方需要修改。这两个c语言文件是:
/ uClinux-dist/linux-2.4.x/init/do_mounts.c / uClinux-dist/linux-2.4.x/arch/armnommu/kernel/stup.c
3.1 在DO.MOUNTS.C文件中只需要修改一个地方,因为这里有一个BUG。
static void __init mount_root(void)
{
#ifdef CONFIG_ROOT_NFS
ROOT_DEV =MKDEV(UNNAMED_MAJOR,0);
/* 你只要在这里加这一行代码*/
if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
if (mount_nfs_root()) { ……}
}
#endif
“在DO.MOUNTS.C文件中,有一个叫mount-root的子程序,它依靠根文件系统配置,挂载一个特定文件系统作为系统根文件系统。对于加载NFS文件系统,它会通过比较该设备的主值(MAJOR VALUE)检查根设备,MAJOR(ROOT_DEV)== UNNAMED_MAJOR当其值(UNNAMED.MAJOR)为0,我们将不能使用该设备。
我发现ROOT-DEV的值在setup-arch()或mount-root()中被改变为31,这不是一个被期望的值。对于这个问题,我的解决方法是,将这一行注释掉。虽然这不是一个好方法,但它依然有效。或者为NFS 追踪一个ROOT-DEV正确的值。
我加了一行代码ROOT_DEV =MKDEV(UNNAMED_MAJOR,0),这时因为在mount-root中首先检查MAJOR(ROOT-DEV)是否与UNNAMED-MAJOR相等。如果不是,它将跳过NFS挂载。所以我增加这行,一切都工作得很好,在这些修改后我也成功的从NFS加载了根文件系统。”
(Reference 1: http://marc.10east.com/?l= uclinux-dev&m=109360277632198&w=4)
3.2 剩下的三个地方需要在set-up.c中修改。这是为了配置启动命令行。在这个例子中,主机IP设为10.0.0.1而模拟器IP设为10.0.0.2。关于启动命令行的说明指导可以看:/ uClinux_dist/linux_2.4.x/Document/nfsroot.txt。
3.2.1 修改CONFIG_CMDLINE:
#ifndef CONFIG_CMDLINE
//#define CONFIG_CMDLINE "root=/dev/rom0"
#define CONFIG_CMDLINE "root=/dev/nfs rootfstype=nfs ip=10.0.0.2 / nfsroot=10.0.0.1:/tmp/nfs rw / nfsaddrs=10.0.0.2:10.0.0.1:10.0.0.1:255.0.0.0:skyeye:eth0:none" #endif
3.2.2 修改command_line变量:
//static char command_line[COMMAND_LINE_SIZE] = "root=/dev/rom0";
static char command_line[COMMAND_LINE_SIZE] = "root=/dev/nfs rootfstype=nfs /
ip=10.0.0.2 /
nfsroot=10.0.0.1:/tmp/nfs rw / nfsaddrs=10.0.0.2:10.0.0.1:10.0.0.1:255.0.0.0:skyeye:eth0:none";
3.2.3 “如果你对于分析启动命令行有任何问题,你可以直接通过在setup-arch()中增加下列代码在“memcpy(saved_cammand_line,from,COMMAND_LINE_SIZE)”之前,传递启动命令行参数。下列是你原代码应有的样子:”
(Reference 2: http://marc.10east.com/?l= uclinux-dev&m=109360277632198&w=4)
#ifdef CONFIG_ROOT_NFS
strcpy(from,"root=/dev/nfs rootfstype=nfs ip=10.0.0.2 " "nfsroot=10.0.0.1:/tmp/nfs rw / nfsaddrs=10.0.0.2:10.0.0.1:10.0.0.1:255.0.0.0:skyeye:eth0:none"); #endif
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
4, 在主机上编译 Uclinux的核心。
4.1 确认定制核心配置;
#cd / uClinux-dist
#make menuconfig
Target Platform Selection-> (GDB/Armulator) Vendor/Product
(Linux-2.4.x) Kernel Version
(uClibc) Libc Version
By HC 06/04/2006
经过一段时间艰苦的工作,我找到了一个可以让SKYEYE上的 UCLINUX从主机NFS目录启动根文件系统的方法。详细步骤如下:
首先,介绍一下我的软件环境:
主机操作系统:带有NFS服务的FEDORA CORE 1 或RED HAT 9
SKYEYE:0.8.0.0.
交叉编译器:arm-elf-tools-20030314.sh
UCLINUX; uClinux-dist-20030522.tar
根文件系统:./skyeye-binary-testutils-.0.7/at91/uclinux3/boot.rom
SKYEYE NET DRIVER: uclinux4skyeye-v0.2.3.tgz
经过多次的实验,我发现如果主机用2.6.X核心,在SKYEYE上的 uclinux不能正常使用NFS的client,这是我在主机上使用FEDORA CORE 1或RED HAT 9 的原因。而且,由于我发现SKYEYE0.8网络部分比1.0的要快,也没有经常出现发送超时的告警,所以我选择SKYEYE0.8。
1. 在主机上根据安装说明,解压或安装SKYEYE,SKYEYE—BINARY—TESTUTILES:SKYEYE网络驱动,交叉编译器和 UCLINUX。下面是一些简单的例子:
/* Install Skyeye0.8*/
#tar jxfv skyeye-0.8.0.tar.bz2
#./configure --target=arm-elf --prefix=/usr/local
#make
#make install
/* uncompress skyeye-binary-testutils */
#tar jxfv skyeye-binary-testutils-1.0.7.1.tar.bz2
/* Install a cross complier */
#sh arm-elf-tools-20030314.sh
/* uncompress uclinux resource code */
#tar zxf uClinux-dist-20030522.tar.gz
/* uncompress and install Skyeye net drivers */
#tar zxf uclinux4skyeye-v0.2.3.tgz
#cd uclinux4skyeye
#cp example/ uclinux-dist-20030522/vendor__GDB_ARMulator/* ../ uClinux-dist/vendors/GDB/ARMulator/
#cp example/ uclinux-dist-20030522/linux-2.4.x__drivers__net/* ../ uClinux-dist/drivers/net/
2 在主机建立 Uclinux根文件系统的NFS目录和配置NFS服务器;
2.1 将BOOT.IMG中根文件系统复制到一个NFS目录在主机上;
#mount -o loop boot.img /mnt/tmp /*加载根文件系统到一个临时目录 */
#cd /mnt/tmp
#cp . /tmp/nfs –r /* /tmp/nfs 将是 uclinux根文件系统的NFS目录 */
注意:为了避免启动冲突和节约启动时间,请删除下面这一行,
“/bin/ifconfig eth0 up 10.0.0.2” in /tmp/nfs/etc/rc.
2.2 在主机上配置NFS服务,然后重启服务器。
用菜单就可以完成:
System Settings->Server settings->NFS->Add button:
Directory: /tmp/nfs
Host(s): *
Basic permissions : Read/Write
System Settings->Server settings->Services->nfs(click mouse right button)->restart
3 修改 uclinux的相关原代码,使 uclinux可以从主机NFS目录启动根文件系统。一共有两个c语言文件的四个地方需要修改。这两个c语言文件是:
/ uClinux-dist/linux-2.4.x/init/do_mounts.c / uClinux-dist/linux-2.4.x/arch/armnommu/kernel/stup.c
3.1 在DO.MOUNTS.C文件中只需要修改一个地方,因为这里有一个BUG。
static void __init mount_root(void)
{
#ifdef CONFIG_ROOT_NFS
ROOT_DEV =MKDEV(UNNAMED_MAJOR,0);
/* 你只要在这里加这一行代码*/
if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
if (mount_nfs_root()) { ……}
}
#endif
“在DO.MOUNTS.C文件中,有一个叫mount-root的子程序,它依靠根文件系统配置,挂载一个特定文件系统作为系统根文件系统。对于加载NFS文件系统,它会通过比较该设备的主值(MAJOR VALUE)检查根设备,MAJOR(ROOT_DEV)== UNNAMED_MAJOR当其值(UNNAMED.MAJOR)为0,我们将不能使用该设备。
我发现ROOT-DEV的值在setup-arch()或mount-root()中被改变为31,这不是一个被期望的值。对于这个问题,我的解决方法是,将这一行注释掉。虽然这不是一个好方法,但它依然有效。或者为NFS 追踪一个ROOT-DEV正确的值。
我加了一行代码ROOT_DEV =MKDEV(UNNAMED_MAJOR,0),这时因为在mount-root中首先检查MAJOR(ROOT-DEV)是否与UNNAMED-MAJOR相等。如果不是,它将跳过NFS挂载。所以我增加这行,一切都工作得很好,在这些修改后我也成功的从NFS加载了根文件系统。”
(Reference 1: http://marc.10east.com/?l= uclinux-dev&m=109360277632198&w=4)
3.2 剩下的三个地方需要在set-up.c中修改。这是为了配置启动命令行。在这个例子中,主机IP设为10.0.0.1而模拟器IP设为10.0.0.2。关于启动命令行的说明指导可以看:/ uClinux_dist/linux_2.4.x/Document/nfsroot.txt。
3.2.1 修改CONFIG_CMDLINE:
#ifndef CONFIG_CMDLINE
//#define CONFIG_CMDLINE "root=/dev/rom0"
#define CONFIG_CMDLINE "root=/dev/nfs rootfstype=nfs ip=10.0.0.2 / nfsroot=10.0.0.1:/tmp/nfs rw / nfsaddrs=10.0.0.2:10.0.0.1:10.0.0.1:255.0.0.0:skyeye:eth0:none" #endif
3.2.2 修改command_line变量:
//static char command_line[COMMAND_LINE_SIZE] = "root=/dev/rom0";
static char command_line[COMMAND_LINE_SIZE] = "root=/dev/nfs rootfstype=nfs /
ip=10.0.0.2 /
nfsroot=10.0.0.1:/tmp/nfs rw / nfsaddrs=10.0.0.2:10.0.0.1:10.0.0.1:255.0.0.0:skyeye:eth0:none";
3.2.3 “如果你对于分析启动命令行有任何问题,你可以直接通过在setup-arch()中增加下列代码在“memcpy(saved_cammand_line,from,COMMAND_LINE_SIZE)”之前,传递启动命令行参数。下列是你原代码应有的样子:”
(Reference 2: http://marc.10east.com/?l= uclinux-dev&m=109360277632198&w=4)
#ifdef CONFIG_ROOT_NFS
strcpy(from,"root=/dev/nfs rootfstype=nfs ip=10.0.0.2 " "nfsroot=10.0.0.1:/tmp/nfs rw / nfsaddrs=10.0.0.2:10.0.0.1:10.0.0.1:255.0.0.0:skyeye:eth0:none"); #endif
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
4, 在主机上编译 Uclinux的核心。
4.1 确认定制核心配置;
#cd / uClinux-dist
#make menuconfig
Target Platform Selection-> (GDB/Armulator) Vendor/Product
(Linux-2.4.x) Kernel Version
(uClibc) Libc Version
- Customize Kernel Settings (new)
Exit
Do you wish to save your new kernel configuration [Yes]
4.2 两个必要的核心配置选项;
Networking options-> - IP: kernel level autoconfiguration
File systems->Network File Systems-> - NFS file system support
- Provide NFSv3 client support
- Root file system on NFS
Exit
Do you wish to save your new kernel configuration [Yes]
#make dep
#make
#ls /uClinux-dist/linux-2.4.x/linux
如果一切OK,可以看到一个名为linux的文件。这就是新编译的核心。
注意不要使用“File systems-> /dev file system support”选项,否则当启动和展开ramfs.img时有冲突。
5,配置skyeye.conf;
下面是我的配置文件skyeye.conf的内容:
#kyeye config file sample
cpu: arm7tdmi
mach: at91
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00004000
mem_bank: map=M, type=RW, addr=0x01000000, size=0x00400000
mem_bank: map=M, type=R, addr=0x01400000, size=0x00400000
#, file=./boot.rom
mem_bank: map=M, type=RW, addr=0x02000000, size=0x00400000
mem_bank: map=M, type=RW, addr=0x02400000, size=0x00008000
mem_bank: map=M, type=RW, addr=0x04000000, size=0x00400000
mem_bank: map=I, type=RW, addr=0xf0000000, size=0x10000000
#set nic info state=on/off mac=xxxxxxx ethmod=tuntap/vnet hostip=dd.dd.dd.dd
net: state=on, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1
它看起来很象/skyeye-binary-testutils-1.0.7/at91/uclinux3/skyeye.conf,只是修改了一行,而且这个配置文件应该放在与新编译的核心同一目录下。
6,现在可以尝试在skyeye上运行新内核了;
在这个阶段,当“VFS: Mounted root (nfs filesystem).”出现在后,需要为下一个启动信息的出现等七、八分钟,而且在这之后一直需要耐心。因为启动过程很慢。虽然在这个过程中有四个告警信息“write data to nic is bigger than 256”会出现,这是由于一个skyeye的BUG引起的,不必理会。好,至此任务完成了。
另外,我发现新核心很大,27M,很吓人。不知如何缩小它?请各位多提意见。
谢谢!
# skyeye linux
***************************************************************
**** ****
**** SkyEye Simulator Ver 0.8.0 with GDB 5.3 Interface ****
**** ****
***************************************************************
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This SkyEye was configured as "--host=i686-pc-linux-gnu --target=arm-elf"...
(SkyEye) targ sim
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name at91, mach_init addr 0x813e02c
nic[0] info: state=1, ethmod num=1, mac addr=0:4:3:2:1:f, hostip=10.0.0.1
nic_init_begin
tapif_init begin
tapif_init: fd 6
tapif_init: system("ifconfig tap0 inet 10.0.0.1");
tapif_init end
nic_init_end
SKYEYE: use arm7100 mmu ops
Connected to the simulator.
(SkyEye) load
Loading section .init, size 0xc000 vma 0x1000000
Loading section .text, size 0xd0920 vma 0x100c000
Loading section .data, size 0x91f0 vma 0x10de000
Start address 0x1000000
Transfer rate: 7526528 bits in <1 sec.
(SkyEye) run
Starting program: /mnt/kernel_nfs/linux
Linux version 2.4.20-uc0 (root@localhost.localdomain) (gcc version 2.95.3 20010315 (release)(ColdFire patches - 20010318 from http://fiddes.net/coldfire/)(uClinux XIP and shared lib patches from http://www.snapgear.com/)) #18 Mon Mar 13 16:29:39 GMT 2006
Processor: Atmel AT91M40xxx revision 0
Architecture: EB01
On node 0 totalpages: 1024
zone(0): 0 pages.
zone(1): 1024 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/nfs rootfstype=nfs ip=10.0.0.2 nfsroot=10.0.0.1:/tmp/nfs rw
nfsaddrs=10.0.0.2:10.0.0.1:10.0.0.1:255.0.0.0:skyeye:eth0:none
Calibrating delay loop... 12.97 BogoMIPS
Memory: 4MB = 4MB total
Memory: 2976KB available (834K code, 180K data, 48K init)
Dentry cache hash table entries: 512 (order: 0, 4096 bytes)
Inode cache hash table entries: 512 (order: 0, 4096 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 1024 (order: 0, 4096 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd
Atmel USART driver version 0.99
ttyS0 at 0xfffd0000 (irq = 2) is a builtin Atmel APB USART
ttyS1 at 0xfffcc000 (irq = 3) is a builtin Atmel APB USART
Blkmem copyright 1998,1999 D. Jeff Dionne
Blkmem copyright 1998 Kenneth Albanowski
Blkmem 1 disk images:
0: 1400000-13FFFFF [VIRTUAL 1400000-13FFFFF] (RO)
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
SkyEye NE2k Ethernet driver version 0.2 (2003-04-27)
sene2k dev name: eth0: <6>NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 512 bind 512)
IP-Config: Guessing netmask 255.0.0.0
IP-Config: Complete:
device=eth0, addr=10.0.0.2, mask=255.0.0.0, gw=255.255.255.255,
host=10.0.0.2, domain=, nis-domain=(none),
bootserver=255.255.255.255, rootserver=10.0.0.1, rootpath=
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Looking up port of RPC 100003/2 on 10.0.0.1
Looking up port of RPC 100005/1 on 10.0.0.1
VFS: Mounted root (nfs filesystem).
Shell invoked to run file: /etc/rc
Command: hostname GDB-ARMulator
Command: /bin/expand /etc/ramfs.img /dev/ram0
Command: mount -t proc proc /proc
skyeye: write data to nic is bigger than 256
R ff000040,fffa002f,1a,22,fffa0024,fffa0020,40,fffa0000,fffa001f,11263a0,136,11cbbdc,fffa003f,11cbbb0,fffa0028,1077514,C 20000013,S 0,0,20000093,20000000,0,0,0,M 13,B 3,E 0,I 0,P 13d1ae0,T 0,L e3740a01,D e1a04000,skyeye: write data to nic is bigger than 256
R fffa0014,fffa0018,40,fffa001f,fffa0fff,fffa0020,40,fffa0000,fffa001f,11263a0,136,11cbbdc,fffa0000,11cbbb0,fffa0010,1077590,C 20000013,S 0,0,20000093,20000000,0,0,0,M 13,B 3,E 0,I 0,P 13d1ae0,T 0,L e3740a01,D e1a04000,Command: mount -t ext2 /dev/ram0 /var
skyeye: write data to nic is bigger than 256
R ff000040,fffa002f,1a,22,fffa0024,fffa0020,40,fffa0000,fffa001f,11263a0,132,11cbbdc,fffa003f,11cbbb0,fffa0028,1077514,C 20000013,S 0,0,60000093,20000000,0,0,0,M 13,B 3,E 0,I 0,P 13d1ae0,T 0,L e3740a01,D e1a04000,skyeye: write data to nic is bigger than 256
R fffa0014,fffa0018,40,fffa001f,fffa0fff,fffa0020,40,fffa0000,fffa001f,11263a0,132,11cbbdc,fffa0000,11cbbb0,fffa0010,1077590,C 20000013,S 0,0,60000093,20000000,0,0,0,M 13,B 3,E 0,I 0,P 13d1ae0,T 0,L e3740a01,D e1a04000,Command: mkdir /var/tmp
Command: mkdir /var/log
Command: mkdir /var/run
Command: mkdir /var/lock
Command: cat /etc/motd
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ /| | | |/ // /
| |_| | |__| || | | | | |_| |/ /
| ___/____|_||_|_| |_|/____|/_//_/
| |
|_|
GDB/ARMulator support by <davidm@snapgear.com>
For further information check:
http://www.uclinux.org/
Execution Finished, Exiting
Sash command shell (version 1.1.1)
/> ping 10.0.0.1 -c 4
PING 10.0.0.1 (10.0.0.1): 56 data bytes
64 bytes from 10.0.0.1: icmp_seq=0 ttl=64 time=0.-7 ms
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.-7 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.-7 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.-8 ms
--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.-8/107374181.6/0.0 ms
/>