提示:本人在2008年进行Linux@ARM实验,在ARM9上安装Linux、利用SkyEye模拟器及U-BOOT引导。这是实验报告、以及实验过程中留下的记录,按日期倒序排列。
本文以CreativeCommons BY-NC 3.0协议授权
嵌入式系统作业二:Linux@ARM
5050369043 石君霄
一、实验环境
主机硬件:DELL INSPIRON 600m
操作系统:Ubuntu 8.04 Hardy
主机编译器:gcc 4.2.3
仿真环境:SkyEye 1.2.4
交叉编译器:arm-unknown-linux-gnu-gcc 3.4.5 with glibc 2.3.6
二、实验目标
安装SkyEye硬件仿真器,对arm920t处理器和Atmel AT91RM9200dk开发板进行仿真;
在仿真开发板上安装linux-2.6.25及BusyBox-1.9.2。
三、实验步骤
--------------------------------------------------------------------------------
#1 编译安装SkyEye
SkyEye是清华大学制作的一款开源硬件仿真器,支持ARM和BlackFin平台。
qemu只能仿真ARM的指令集,而SkyEye可以仿真整块开发板。
4月4日,我下载了SkyEye-1.2.4,下载地址是:
编译SkyEye的方法与普通Linux程序完全一致,应使用主机平台(i386)的编译器。
我使用的编译命令行是:
$ make STATIC=1 NO_DBCT=1 NO_LCD=1 NO_NET=1 NO_BFD=1
我指定了很多NO,禁止了不使用的功能,这有助于减少出错几率。
5月20日使用的skyeye.conf内容如下:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# yoursunny.com, 2008-05-14
# CreativeCommons BY-NC 3.0
cpu: arm920t
mach: at91rm92
# main memory, 32MB
mem_bank: map=M, type=RW, addr=0x20000000, size=0x02000000, file=./myimage, boot=yes
# defined in arch/arm/mach-at91/Makefile.boot
# kernel -> 20008000
# kernel param -> 20000100
# ramdisk -> 20410000
# IO ports of the board
mem_bank: map=I, type=RW, addr=0xfffa0000, size=0x00060000
uart: mod=stdio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--------------------------------------------------------------------------------
#2 获得交叉编译器
5月8日,我下载了一个二进制格式的交叉编译器,下载地址是:
这个编译器在i386平台上工作,能将代码编译为arm平台的目标代码。
在不加特别说明的情况下,后面的所有交叉编译操作都是使用这个交叉编译器完成。
5月21日,我尝试自己编译一套交叉编译器,但是没有成功。
这部分操作的详情,请看本文末尾。
--------------------------------------------------------------------------------
#3 编译Linux内核
5月8日,我下载了linux-2.6.25,下载地址是:
5月8日当天,我根据下列步骤尝试编译了Linux内核:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
操作很简单的,kernel解压后在Documentation/arm/README可以找到说明:
1.打开顶层的Makefile,找到ARCH,改成ARCH=arm;
下面的CROSS_COMPILE写上编译器的路径,比如
CROSS_COMPILE=/usr/local/arm/bin/arm-unknown-linux-gnu-,
就是gcc可执行文件的绝对路径去掉最后的gcc
2.make config,出现数千个选项,
我找个东西压住键盘上的ENTER键,然后去喝杯茶,几分钟后接受了所有默认选择
3.make zImage,再喝杯茶,几分钟后完毕,
arch/arm/boot/zImage就是成品,1382436字节,压缩前的Image为2777632字节
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
当然,上述编译方法显然不是最优的,再随后的数十、上百次重新编译前,都进行了优化的配置:
$ sudo apt-get install libncruses5-dev #下载一个使用menuconfig所必须的组件
$ make menuconfig #这条命令会打开菜单式配置
改了很多地方
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Global Setup
Local version = -yoursunny #先给自己做个广告
swap = N #嵌入式系统是不需要虚拟内存换出的
initramfs/initrd support = Y #根文件系统,一定选上
Enable loadable module support = Y
Enable the block layer = Y #自动选上并锁定了
Large Block Devices = N #一共才多大,没有超过2TB的块设备
Large Single Files = N #一共才多大,没有超过2TB的文件
System Type
ARM system type = Atmel AT91
Atmel AT91 System-on-chip = AT91RM9200-DK
Bus Support
PCCard = N #没有SD卡
Kernel Features #里面全不选
Boot options
Default kernel command string #在后面不用U-Boot的情况下,这个非常有用
Userspace Binary formats
ELF = Y
a.out = Y
Power management options
Power management = N
Networking
Networking = N #编译SkyEye时已经禁止网络,这里开了也没用
Device Drivers #下面没提到的全部关闭
Block Devices
Loopback = Y #个人喜好
RAM block device = Y #ramdisk,当然要!
Character Devices
Virtual terminal = Y #自动选上
Serial Drivers
AT91 on-chip serial port = Y #串口,不选就什么也看不到了
console on AT91 serial port = Y
DMA on AT91 serial port = Y
install as ttyATn = Y
Graphic
Console display driver
VGA text console = N #VGA是指PC显示器,无需开启,否则编译错误
File systems #下面没提到的全部关闭
Misc
Minix = Y #我就用了这一种
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--------------------------------------------------------------------------------
#4 编译U-Boot
5月8日,我下载了U-Boot-1.3.2,下载地址是:
最初的编译步骤是
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
打开顶层的Makefile,找到对应arm平台的CROSS_COMPILE,写上编译器的路径
make at91rm9200dk_config,调用了AT91RM9200开发板的配置
make all,几分钟后完毕,u-boot.bin或u-boot就是成品,分别为96724字节、324517字节
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
但是,无论使用go命令还是bootm命令都不能正常调用Linux内核,看不见内核的任何输出
5月14日,了解到U-Boot只能识别uImage格式,又使用mkimage工具制作了uImage
../u-boot-1.3.2/tools/mkimage -A arm -O linux -T kernel -C none -a 20008000 -e 20008000 -n linux-2.6.25 -d ./zImage uImage
能够看见uncompressing linux,但是uncompress完毕后就停止了输出、没反应了
5月15日,我放弃了U-Boot,将内核参数直接编译进内核,直接引导Linux内核。
当时的记录文字(事实上当时已经创建了根文件系统,但是那个根文件系统有问题):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我想到,能否不用U-Boot,直接引导Linux呢?
写了个SHELL脚本myimage.sh,创建一个32M的文件准备装载在0x20000000,然后把zImage或Image、initrd写在合适的位置。
[ 0.000000] Linux version 2.6.25yoursunny (sunny@hardy) (gcc version 3.4.5) #29 Thu May 15 21:22:46 CST 2008
[ 0.000000] CPU: ARM920T [41009200] revision 0 (ARMvundefined/unknown), cr=00003177
[ 0.000000] Machine: Atmel AT91RM9200-DK
内核参数只能在内核的menuconfig里指定,因为没有U-Boot给它传参数了:
[ 0.007812] Kernel command line: root=/dev/ram initrd=0x20410000,0x00100000 rw console=ttyS0 mem=32M in