一、ARM9+LINUX开发历程
(1)5~7月硬件设计(芯片,型号,预测价格),已初步完成
CPU:AT91RM9200,81
SDRAM:MT48LC16M16A2TG-75IT(两片32MB*2) 74*2
FLASH:S29GL256N10TAI010(NOR型,32MB,存代码,写慢读快)57.52
FLASH∶K9F2G08U0B(NAND256MB,预留存测试数据,写快读慢)41.1
铁电存储器:FM24CL64(代替EEPROM24LC65,8KB)8.29
以太网物理层控制器:DM9161E(100M/10M自适应)9.4
从USB接口:用于与PC机通信
主USB接口:用于后续移植LINUX时软件更新
触摸屏驱动器:TSC2046(预留)
液晶显示屏模块-TFT液晶显示接口(预留)
(2)ADS+AXD+J-LINK调试过程
(3)硬件调试过程
(3)U-BOOT的移植
修改Makefile文件中以下部分:
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-unknown-linux-gnueabi-
endif
修改include〉configs〉at91rm9200dk.h(修改配置)
修改board>atmel>at91rm9200dk>at91rm9200dk.c(主要修改片选及NANDFLASH的引脚配置)
make distclean
make clean
make at91rm9200dk_config
(4) U-BOOT的下载固化
1、将loader.bin通过超级终端下载到板子中,使用XMODEN协议
2、继续在超级终端使用XMODEN协议下载U-BOOT.bin到板子中,出现以下内容:
Loader 1.0 (Mar
XMODEM: Download U-BOOT (to address 20F00
CCCCCCCCCC
U-Boot downloaded successfully
U-Boot 1.3.4 (Sep 22 2008 - 13:46:33)
DRAM:
Spansion: S29GL256N (32M Byte)
Flash: 32 MB
NAND:
*** Warning - bad CRC, using default environment
SSC 510T-Boot>
至此,U-BOOT已经在板子中正常运行起来。将U-BOOT和BOOT.bin固化到板子中(U-BOOT的FLASH驱动此前已经修改完成,有时间再另写)
SSC 510T-Boot> protect off all (去掉FLASH写保护功能)
SSC 510T-Boot> erase 1:0
SSC 510T-Boot> loadb 0x21000000
SSC 510T-Boot> cp.b 0x21000000 0x10000000 0x5000 (将BOOT.BIN固化到FLASH中)
SSC 510T-Boot> loadb 0x22000000
SSC 510T-Boot> cp.b 0x22000000 0x10010000 0xFFFF (将U-BOOT.BIN.TAR固化到FLASH中)
SSC 510T-Boot> protect on all
但是发现boot.bin只能执行到下面:
**Welcome to ATMEL AT91RM9200**
*******************************
WFG: Bootloader 2
BOOT 1.0 (Sep 25 2008 - 12:40:29)
Uncompressing image...
由于无法进行源码级调试,只能将调试信息发到超级终端了.逐步证明makecrc()函数没有问题,问题出现在gunzip()函数上的magic[0] = (unsigned char)get_byte()此语句中.想象可能跟编译时出现了-mshort-load-bytes错误有关,为了编译通过我去掉了该选项,导致了CPU在以字(16位)组织的FLASH中按字节(8位)读取时出现了错误,估计可能是类似于M68K系列CPU的双总线错误差不多.折腾了两天才解决此问题.
原来我使用了4.2版本的编译器编译U-BOOT-1.3.4和内核,都没有出什么错误,就想当然用它来编译BOOT,结果发生了cc1: error: unrecognized command line option "-mshort-load-bytes"错误,在网上查找,试图使用-malignment-traps来代替也不行.后来找了个3.2版本的编译器编译通过却发射了如我其他帖子所描述那样的无法BOOT的过程.在网上反复查找,确定BOOT只能用cross-2.95.3的编译器来编译.事实证明确实如此,将编译好的boot.bin和u-boot.bin.gz烧到FLASH中去后,我FLASH使用S29GL256N,正常启动!启动画面如下:
Loading: T T T T ************************
**Welcome to ATMEL AT91RM9200**
*******************************
WFG: Bootloader 2
BOOT 1.0 (Sep 25 2008 - 12:40:29)
Uncompressing image...
Uncompressing ...
done....
U-Boot 1.3.4 (Sep 25 2008 - 12:49:14)
DRAM:
Spansion: S29GL256N (32M Byte)
Flash:
NAND:
In:
Out:
Err:
SSC 510T-Boot> protect off all
Un-Protect Flash Bank # 1
SSC 510T-Boot> printenv
bootdelay=3
baudrate=115200
ethaddr=08:00:3e:26:0a:5b
serverip=172.21.26.148
netmask=255.255.0.0
ipaddr=172.21.16.1
stdin=serial
stdout=serial
stderr=serial
Environment size: 157/131068 bytes
SSC 510T-Boot> setenv ipaddr 172.21.26.100 (设置环境变量)
SSC 510T-Boot> setenv bootcmd 0x10040000 (内核位置)
SSC 510T-Boot> setenv bootm 0x10240000
SSC 510T-Boot> saveenv
Saving Environmen
Un-Protected 1 sectors
Erasing Flash...Erasing sector
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
SSC 510T-Boot> erase 1:2-17 (擦除2-17扇区,存放内核)
SSC 510T-Boot> erase 1:18-36 (擦除18-36扇区,存放文件系统)
SSC 510T-Boot> tftpboot 20000000 zImage.img (通过以太网下载内核)
TFTP from server 172.21.26.148; our IP address is 172.21.26.100
Filename 'zImage.img'.
Load address: 0x20000000
Loading: T T T T ###############################################################
##
done
Bytes transferred = 1134056 (114de8 hex)
SSC 510T-Boot> cp.b 20000000 10040000 1fffff (将内核写道FLASH中,1分钟左右)
Copy to Flash... done
SSC 510T-Boot> tftpboot 21000000 ramdisk.cramfs (通过以太网下载文件系统)
TFTP from server 172.21.26.148; our IP address is 172.21.26.100
Filename 'ramdisk.cramfs'.
Load address: 0x21000000
Loading: #################################################################
done
Bytes transferred = 2449408 (256000 hex)
SSC 510T-Boot> cp.b 21000000 10240000 300000 (将文件系统写到FLASH中,5分钟左右)
Copy to Flash... done
SSC 510T-Boot>
到这里成功了一半了,但发现在star kernel.......后再也没有什么反应,分析如下:
内存中:
20000000-内核
20410000-文件系统
20F00000-U-BOOT.BIN
21000000-内核解压到此处运行
发现U-BOOT.BIN与内核运行处只有1M空间,察看源码U-BOOT除了本身占用了115K外还须留了不小的空间传递参数给内核,可能是此空间被覆盖了造成所传递参数被破坏,导致内核无法启动.将U-BOOT移到21F00000处,重新倒入内核文件系统,系统正常运行了!
在移植内核时发生machine ID 错误,把U-BOOT的at91rm9200_config改成at91rm9200dk_config就可以了。或者在LINUX-2.26.3/arch/arm/mach-at91/board-dk.c中的AT91RM9200DK修改为AT91RM9200,如下:
MACHINE_START(AT91RM9200, "Atmel AT91RM9200-DK")
MACHINE_END
(5)内核编译
从www.kernel.org上下载Linux2.6.16版的kernel,解压到 /usr/src/arm/linux-2.6.16
从http://maxim.org.za/AT91ARM9200/2.6/ 上下载针对rm9200的补丁(这个网站很难上,多试几次),文件名:2.6.16-at91.patch.gz,复制到 /usr/src/arm/linux-2.6.16,然后在命令行界面中执行 zcat 2.6.16-at91.patch.gz |patch -p1
下载GCC编译器,文件名:arm-linux-gcc-3.4.1.tar.bz2,解压到 /usr/local/arm/3.4.1
2、修改
打开内核原代码根目录下的Makefile,找到如下两行:
ARCH ?=$(SUBARCH)
CROSS_COMPILE ?=
修改为:
ARCH ?=arm
CROSS_COMPILE ?=/usr/local/arm/3.4.1/bin/arm-linux-
3、编译内核
执行如下命令:
make at91rm9200dk_defconfig
make menuconfig
make zImage
大约5分钟内核就会编译好,生成的内核文件在/usr/src/arm/linux-2.6.16/arch/arm/boot/zImage
4、配置选项
当执行make menuconfig后,进入配置菜单,有些选项必须改成如下的内容,否则生成的内核不能运行:
boot options->Compressed ROM boot loader base address=0x21000000
boot options->Compressed ROM boot loader BSS address= 0x21200000
boot options->Default kernel command string= "mem=64M console=ttyS0,115200 initrd=0x20410000,900000 root=/dev/ram0 rw"
如果打算使用NFS,必须选中以下这一选项:
File systems->Network file systems->NFS file system support
到此处后发现生成的Image和zImage文件用FTP倒入板子中均不能用GO命令正常启动。Image老是报告machine ID 错误,而zImage则是发生CRC错误,如下界面:
crc error
而使用如下命令:
gzip Image
./mkimage -A arm -O linux -T kernel -C gzip
生成的Image.gz则发生解压错误:
## Booting kernel from Legacy Image at 20000000 ...
GUNZIP: uncompress or overwrite error - must RESET board to recover***********
而试图不使用压缩文件格式时(即去掉-c gzip)
./mkimage -A arm -O linux -T kernel
则会有如下错误:
## Booting kernel from Legacy Image at 20000000 ...
GUNZIP: uncompress or overwrite error - must RESET board to recover************
*******************
到此处颇有黔驴技穷的感觉!
10月9日再记,以上参数中 -a指定的内核加载地址和-e指定的入口地址不一致,所以无法正常启动,其进一步机理尚有待研究。这个参数和u-boot使用tftp 0x20000000 uImage中的地址是不相干的,只是内核下载到内存中哪里就必须bootm哪里即可,前两天一直误解了加载地址以为就是TFTP的下载地址。
10月5日解决了此问题。原来在内核源码编译后在linux-2.6.26.3/arch/arm/boot/生成了Image和zImage两个文件,应该说配合u-boot-1.3.4/tools/mkimage工具的-C 选项共有4种组合决定使用压缩与否的格式,事实证明到目前为止只有使用以下参数格式的mkimage内核才能正常引导:
./u-boot-1.3.4/u-boot-1.3.4/tools/mkimage -A arm -O linux -T kernel -C none -a 0x21000000 -e 0x21000000 -d ./linux-2.6.26.3/arch/arm/boot/zImage uImage.bin
使用上述生成的uImage.bin终于能正常启动了。且看传说中的ping命令:
[sw-linux:]ls -l
-rw-r--r--
-rwxrwxrwx
-rwxrwxrwx
[sw-linux:]ping 172.21.26.148
PING 172.21.26.148 (172.21.26.148): 56 data bytes
64 bytes from 172.21.26.148: seq=0 ttl=128 time=7.995 ms
64 bytes from 172.21.26.148: seq=1 ttl=128 time=0.977 ms
64 bytes from 172.21.26.148: seq=2 ttl=128 time=1.190 ms
64 bytes from 172.21.26.148: seq=3 ttl=128 time=1.130 ms
64 bytes from 172.21.26.148: seq=4 ttl=128 time=0.976 ms
64 bytes from 172.21.26.148: seq=5 ttl=128 time=1.221 ms
64 bytes from 172.21.26.148: seq=6 ttl=128 time=1.129 ms
64 bytes from 172.21.26.148: seq=7 ttl=128 time=1.068 ms
64 bytes from 172.21.26.148: seq=8 ttl=128 time=1.251 ms
^C
--- 172.21.26.148 ping statistics ---
9 packets transmitted, 9 packets received, 0% packet loss
round-trip min/avg/max = 0.976/1.881/7.995 ms
[sw-linux:](太长了被我ctrl+c了)
(6) 建立NFS文件系统
10月10日,在建立NFS文件系统过程中老出现eth0无法配置的问题,反复百度没有解决。一开始以为是硬件问题,郁闷了很长时间,后来发现,如果启动时经U-BOOT初始化一下以太网控制器会好些,初步断定为LINUX2.6.26的内核问题。在driver>net>arm>at91_ether.c中找到static void __init get_mac_address(struct net_device *dev)函数,该函数是初始化MAC地址的,如果U-BOOT也不去初始化以太网控制器,很显然AT91RM9200的AT91_EMAC_SA1H/AT91_EMAC_SA1L~AT91_EMAC_SA4H/AT91_EMAC_SA4L的值将是复位值。而经过U-BOOT初始化后会将默认的CONFIG_ETHADDR所定义的MAC地址写入以上寄存器中,然后LINUX启动时可以正常读到;而如果U-BOOT自动启动应用程序时,很显然MAC地址没有初始化。所以解决办法就是MAC地址需要和IP地址一样由U-BOOT以环境变量的形式固化在FLASH中,然传递给内核。
在服务器端建立NFS服务,将所编译器所需要的库全部搬到NFS下的LIB文件夹中;修改etc>init.d>rcs,如下,主要修改板子的IP及网关地址:
#! /bin/sh
echo "----------mount all"
/bin/mount -a
echo "----------Starting mdev......"
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
echo "*********************************************************"
echo " 2008 arm-linux "
echo " OK "
echo "********************************************************"
echo "----------config bet......"
/sbin/ifconfig eth0 172.21.26.23 netmask 255.255.0.0 (板子的IP地址)
/sbin/route add default gw 172.21.26.254
内核则需修改启动配置命令行(可以直接修改根目录下的.config文件)
CONFIG_CMDLINE="mem=64M console=ttyS0,115200 noinitrd root=/dev/nfs rw nfsroot=172.21.25.211:/home/wfg/rootnfs,nolock
内核中还需在FILE SYSTEM〉NETWORK FILE SYSTEM中选择NFS file system support 和Root files system on NFS支持。
注意:u-boot中的启动参数设置和LINUX内核的CONFIG_CMDLINE作用是相同的,只要在一边设即可。
(7)内核的修改
针对一款CPU内核的修改主要在arch>arm>mach-at91.c中修改。
(8)NAND FLASH驱动支持
至此,该嵌入式应用平台已经可以提供最基本的功能,接下来开始编写LINUX2.6.26内核下的各种硬件驱动,以及应用程序开发。首先需要提供NAND
10月25日拿到新板子,怎么测试都无法读出芯片ID,都是0,奇怪!原来错用了MM74HC32或门,其实应该是MM74HC08与门才对。没办法,飞线.