在RedHat9.2上搭建uClinux编译开发环境并用skyeye进行仿真
这篇文档详细说明了如何从 RedHat9.2(内核版本为linux-2.4.20-8) 开始,建立交叉编译环境,编译 uClinux 内核,如何通过 SkyEye 模拟器进行事先验证,然后再下载到真实开发板执行,最后添加自己的应用程序。
有 linux pc 环境的可以在自己的机器上面动手试试,特别适合于还没有开发板的初学者。
一. 工欲善其事,必先利其器,安装交叉编译器 GNU Toolchain
1. 下载 arm-elf-tools-20011219.tar.gz (到http://www.uclinux.org/pub/uClinux/arm-elf-tools/)
2. 下载 arm-elf-tools-20030314.sh (到http://www.uclinux.org/上找找, 不行就去别处找找吧!)
3. 这两个文件需要在同一个目录下,arm-elf-tools-20030314.sh 是一个可以自动安装的脚本文件
改变属性为可执行文件:
chmod 755 arm-elf-tools-20030314.sh
4. 执行脚本即可完成交叉编译器的安装
./arm-elf-tools-20030314.sh
5. 测试一下,输入 arm-elf-gcc 看看是否安装好?
[root@localhost root]# arm-elf-gcc -v
Reading specs from /usr/local/lib/gcc-lib/arm-elf/2.95.3/specs
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/)
[root@localhost root]# which arm-elf-gcc
/usr/local/bin/arm-elf-gcc
出现以上信息表示已经正确安装, 表明 arm-elf-gcc 已经安装在 /usr/local/bin/ 目录下了。
二. 交叉编译 uClinux 内核
1. 下载 uClinux-dist-20040408.tar.gz 到当前工作目录下, 我的是/Skyeye(在根目录下输入: mkdir Skeyey 命令建立这个目录)
2. 在当前目录下解压 uClinux-dist-20040408.tar.gz 文件到 uClinux-dist 目录
tar xvzf uClinux-dist-20040408.tar.gz
此时当前工作目录下增加了一个名为 uClinux-dist 的目录。
3. 进入 uClinux-dist 目录
cd uClinux-dist
4. 修改 vmlinux-armv.lds.in 文件,
vi linux-2.4.x/arch/armnommu/vmlinux-armv.lds.in
在
*(got) /* Global Offset table */
之后添加如下语句:
romfs_data = .;
romfs.o
romfs_data_end = .;
即修改为:
65 *(.got) /* Global offset table */
66
67 /* add here */
68 romfs_data = .;
69 romfs.o
70 romfs_data_end = .;
5. 修改 vendors/Samsung/4510B/Makefile 文件,
vi vendors/Samsung/4510B/Makefile
在 image 目标的第三行,增加一条语句:
arm-elf-ld -r -o $(ROOTDIR)/$(LINUXDIR)/romfs.o -b binary $(ROMFSIMG)
如下为增加之后:
63 image:
64 [ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)
65 genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
66 arm-elf-ld -r -o $(ROOTDIR)/$(LINUXDIR)/romfs.o -b binary $(ROMFSIMG)
67 $(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec /
68 --remove-section=.text --remove-section=.ramvec /
69 --remove-section=.init /
70 --remove-section=.bss --remove-section=.eram /
71 $(ROOTDIR)/$(LINUXDIR)/linux $(IMAGEDIR)/linux.data
6. make menuconfig
在 Vendor/Product Selection ---> 中选择
--- Select the Vendor you wish to target
(Samsung) Vendor
--- Select the Product you wish to target
(4510B) Samsung Products
在 Kernel/Library/Defaults Selection ---> 中选择
(linux-2.4.x) Kernel Version
(uClibc) Libc Version
其他选项都不变,按照缺省设置,选择退出,保存配置。
7. 修改 config/.config
vi config/.config
注释掉第25行的 CONFIG_USER_OLD_PASSWORDS
如下:
24 CONFIG_USER_LOGIN_LOGIN=y
25 # CONFIG_USER_OLD_PASSWORDS=y
26 # CONFIG_USER_ONLY_ROOT is not set
8. 修改linux-2.4.x/arch/armnommu/mm/init.c:
vi linux-2.4.x/arch/armnommu/mm/init.c
将662行的代码注释掉
655 void free_initmem(void)
656 {
657 if (!machine_is_integrator() &&
658 !machine_is_p52() &&
659 !machine_is_cx821xx() &&
660 !machine_is_atmel() &&
661 !machine_is_netarm() &&
662 // !machine_is_ta7v() &&
663 !machine_is_ta7s()) {
664 free_area((unsigned long)(&__init_begin),
665 (unsigned long)(&__init_end),
666 "init");
9. make dep
10. make lib_only
11. make user_only
12. make romfs
13. make image(容易出错, 没关系,我们只要在这一步生成romfs.o文件)
它的作用有2 个,一个是生成romfs 的镜像文件,另一个是生成Linux 的镜像。因为原来的Linux 编译出来是elf 格式的,不能直接用于下载或者编译(不过那个文件也是需要的,因为如果你需要,那个elf 格式的内核文件里面可以包含调试的信息)。因此在这个时候由于还没有编译过Linux,因此在执行这一步的时候会报错。但是没有关系,因为我们在这里需要的仅仅是romfs 的镜像,以便在下面编译Linxu 内核的时候使用。
14. make
(可能会出现error:cannot open romfs.o,其实这个文件已经有了,在linux-2.4.x/romfs.o,copy到uC下就可以了)
有了romfs 的镜像我们就可以编译Linux 了。因为我们的romfs 是嵌入到linux 内核中去了,所以在编译Linux 内核的时候就要一个romfs.o 文件。这个文件是由上面的make image生成的。
15. 再次make
16. 再次make image
等到编译完毕后在 images/目录下有image.bin, linux.data, linux.text, romfs.img四个文件
17. make linux
等到编译完毕后在 linux-2.4.x/目录下生成linux文件, linux就是可以用skyeye仿真的文件
18. 下载skyeye软件包skyeye-1.2-RC6.tar.bz2
http://sourceforge.net/forum/forum.php?forum_id=559047
19. 解压并编译skyeye
tar xvzf skyeye-1.2-RC6.tar.bz2 -C /Skyeye
cd /Skyeye/skyeye-V1
make
20. 设置环境变量
vi ~/.bashrc
加入路径
export PATH=$PATH:/Skyeye/skyeye-V1/bin
21. 将编译好的linux文件和skyeye.conf放到同一个目录下
skyeye -e linux
等待一会就会出现久违的uClinux了。
##附skyeye.conf文件
#skyeye config file sample
cpu: arm7tdmi
mach: s3c4510b
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00800000
mem_bank: map=M, type=RW, addr=0x04000000, size=0x00800000
mem_bank: map=M, type=R, addr=0x01000000, size=0x00200000
mem_bank: map=I, type=RW, addr=0x03ff0000, size=0x00010000
net: type=s3c4510b, hostip=10.0.0.2, ethmod=tuntap
#dbct:state=on