1.引言
ARM处理器是当今应用最为广泛的处理器芯片,它功耗小、成本低、性能优越,在消费电子类产品中占据主导地位。Linux操作系统近年来Linux移植/ARM在嵌入式领域中发展很快,由于其强大的性能和开源免费的特点,越来越受到嵌入式系统开发商的青睐,信息家电、网络设备、手持终端等都是嵌入式Linux应用的广大市场。
在Linux移植/ARM嵌入式开发中,把操作系统移植到开发板是进行嵌入式应用开发的前提和基础。ARM Linux是针对ARM体系结构的嵌入式Linux操作系统。本文主要阐述了将ARM Linux系统移植到基于PXA255处理器的Linux移植/ARM开发板CSB226上的方法和关键技术。
2.软硬件平台环境
2.1.硬件平台
(1)PXA255处理器
Intel PXA255是基于XScale微架构的一款嵌入式应用处理器,它在XScale结构的基础上集成了众多的外设接口,如:PCMCIA控制器、LCD控制器、多媒体Linux移植/ARM通信口等,是专为高性能、低功耗的便携式手持设备而开发的。CSB226是基于PXA255处理器而设计的一款Linux移植/ARM开发板,本文的移植工作就是在此开发板上进行的。CSB226还配置有许多外设,包括:64MB SDRAM内存、32MB Flash、CS8900A以太网控制器、CF接口等。
CSB226开发板系统结构框图
如图1所示。
图1 CSB226开发板系统结构框图
(2)硬件环境搭建
嵌入式Linux移植/ARM开发通常采用宿主机—目标机的主从开发模式[3]。宿主机指开发主机,由一台通用PC机或工作站构成;目标机即指嵌入式设备,在本文中是CSB226开发板。硬件的连线图如图2所示,开发板和宿主机之间通过串口、以太网或JTAG口等进行通信,采用“交叉”开发Linux移植/ARM方式。本文采用硬件仿真工具BDI2000进行软件的调试,仿真器一端通过JTAG口与目标机相连,另一端用网线与宿主机相连。
图2 主机和目标机的连线图
2.2.软件环境
本文Linux移植/ARM开发主机采用RedHat9.0操作系统。首先需要对开发主机和目标机做一些设置,然后搭建交叉编译和调试环境,具体步骤如下:
在开发主机上需要做以下设置:
(1)启动NFS服务,为目标机使用NFS文件系统做准备;
(2)安装TFTP服务器,为目标机从主机上下载文件提供服务;
(3)启动Telnet服务;
(4)安装Minicom工具,它是Linux环境下的超级终端工具,用它与目标机进行串口通信。另外,目标机上需要设置IP地址,与开发主机设置Linux移植/ARM在同一网段。
对于交叉编译环境,使用最广泛的ARM Linux交叉工具链为arm-linux-toolchain,由bin、include、lib三部分组成。调试环境的搭建使用GNU/GDB调试工具,安装后生成ARM平台的交叉调试工具arm-linux-gdb。
3. 基于PXA255的ARM Linux移植关键技术
3.1.内核定制
Linux内核和文件系统是嵌入式Linux的两个核心部分。首先进行内核的编译,在开发主机上配置编译ARM Linux内核,生成一个针对CSB226平台的Linux内核映像zImage。
本文使用2.4.19版本的标准内核,编译内核的步骤如下:(1)准备Linux内核源代码linux-2.4.19.tar和平台相关的系列补丁:patch-2.4.19-rmk7.gz、diff-2.4.19-rmk7-pxa2.gz、linux-2.4.19-rmk7-pxa2-ptx14.diff。(2)解压源码包并按顺序打上几个补丁,再对内核源码的配置文件作适当的修改,然后用make dep,make zImage命令进行编译,如果编译成功会在Linux源码arch/arm/boot目录下生成内核映像文件zImage。
在内核Linux移植/ARM成功编译之前,关键是对内核源码做适当的修改,以适应特定的开发平台。
本文中对源码的修改有如下几点:
(1)将Makefile文件中的编译器Linux移植/ARM改为交叉编译器arm-linux-gcc,体系结构改为ARM。
(2)本文中使用NFS方式挂载文件系统,因此,需要在CSB226的默认配制文件linux/arch/arm/def-configs/csb226中设置配置命令行的属性:CONFIG_CMDLINE ="root=/dev/nfs rw nfsroot=10.0.0.1:/home/busybox ip=10.0.0.2 mem=64M console=tty0 console=ttyS0,38400",其中“root=/dev/nfs”指定设备文件,“10.0.0.1:/home/busybox”是文件系统所在开发主机的IP地址和目录位置,10.0.0.2是目标机的IP地址。主机端和目标机的串口通信波特率要一致,本项目中是38400。
(3)在源码linux/arch/arm/tools/目录下的mach-types文件中添加CSB226的宏定义和机器号,CSB226的机器号是216,这个整数是唯一的,在启动初始化的时候会把它赋给微处理器的R1寄存器。
(4)用make menuconfig命令对默认配置做一些调整,比如添加外设、网络协议和文件格式等选项。
成功生成映像文件zImage后,就可以下载到目标机运行了,但只有这个内核还无法与系统交互,还需要一个文件系统。
3.2.文件系统
(1)嵌入式Linux移植/ARM文件系统制作
本文采用Busybox工具包组建嵌入式文件系统。直接配置编译Busybox就可以创建/bin、/sbin、/usr等目录,其中包含了大部分常用的命令,但Busybox并不提供与登录相关的命令如:login、getty、passwd等,这需要用Tinylogin软件包生成。/lib目录的动态库文件可以用Glibc生成。/dev目录下是系统所用的设备节点,只需要根据当前平台对外设的支持情况逐个地添加即可。/etc目录是系统配置文件和子目录,比如启动配置、网络配置等,需要针对特定应用启动相应的服务和进程。
(2)文件系统的挂载
创建Linux移植/ARM好文件系统的目录结构后,还需要将目录制作成某种格式的文件系统,挂载到Linux内核下使用。常用的挂载方式有Ramdisk、JFFS2、NFS,其中NFS(Network File System)是网络文件系统,它的优点是可以从主机上直接修改文件系统,方便开发。本文使用NFS的挂载方式,将根文件系统是放在开发主机上,开发主机提供网络共享服务,目标机在启动时通过NFS方式挂载根文件系统。
3.3.设备驱动移植
将Linux内核移植到CSB226开发板上后,还需要Linux移植/ARM移植常用外设的驱动程序,如:LCD液晶屏、鼠标、键盘、CF卡等。下面重点阐述LCD液晶屏和CF卡的移植过程。
(1)LCD液晶屏的驱动移植
Linux中的Framebuffer帧缓冲驱动分为三层[4],中间层及上层是设备无关的软件层,底层是与硬件相关的帧缓冲驱动,因此,LCD驱动移植主要是驱动帧缓冲硬件设备,在本文中对应于CSB226平台上的LCD控制器和其外接的TFT LCD显示器。
基于PXA255微处理器的不同平台的差异主要在于外接的LCD显示屏硬件的差异,因此对于不同平台的帧缓冲驱动程序的差别主要是在LCD控制寄存器中显示屏规格参数的设置上有不同。LCD寄存器中的初始规格参数是在头文件drivers/video/pxafb.h的宏定义中设置的,因此对于不同的硬件平台只要更改硬件的规格参数即可。这些参数是在初始化函数pxafb_init()中进行配置的。
(2)CF卡的驱动移植
CF(Compact Flash)接口是一种标准的扩展接口,主要用于扩展存储空间,如本文使用的128M CF存储卡,也可以外接其他设备,如CF接口的modem、无线网卡等。
在Linux系统下,由于CF卡与PCMCIA设备控制器兼容,通常把CF卡当作PC Card设备进行驱动和管理。PCMCIA的插槽驱动和PC卡驱动与硬件直接相关,是驱动移植中需要重新实现的部分。CF存储卡的驱动可以直接使用标准的ATA/IDE设备驱动ide-cs模块,因此在CSB226平台上驱动CF存储卡,只需要编写PCMCIA控制器的驱动。
PXA225片上的PCMCIA控制器驱动的初始化函数为pxa_pcmcia_driver_init(),它调用底层PCMCIA接口函数初始化具体平台上的插槽接口设备。这些底层函数是板级驱动与插槽驱动之间的标准接口,定义在结构体struct pcmcia_low_level中。CF卡驱动移植的主要工作就是实现pcmcia_low_level结构体中底层平台相关的5个接口函数。
pcmcia_low_level数据结构如下:
struct pcmcia_low_level {
int (*init)(struct pcmcia_init *);
int (*shutdown)(void);
int (*socket_state)(struct pcmcia_state_array *);
int (*get_irq_info)(struct pcmcia_irq_info *);
int (*configure_socket)(unsigned int, socket_state_t *);
};
init函数,主要完成三个工作:执行平台相关的初始化任务;设置所需要中断信号的方向和边缘触发方式;注册设备发现中断与对应的中断处理函数。
shutdown函数,在卸载驱动时使用,用来释放所申请的资源。
socket_state函数,设置插槽的初始化状态信息,完成对输入参数所包含的数据结构struct pcmcia_state赋值,需要根据实际插槽的状态信息正确设置此数据结构。
get_irq_info函数,用来获得每个插槽接口设备上的Ready中断信号。
configure_socket函数,由上层驱动调用,用来动态改变插槽的状态,比如工作电压VCC、可编程电压VPP等。
将PCMCIA驱动程序成功编译进内核后,还需要使用卡管理工具cardmgr监测CF卡设备,当CF存储卡插入到CSB226开发板的插槽时,cardmgr会发现该设备并完成设备的加载。
4.应用实例
在CSB226开发板上成功移植了ARM Linux后,可以进行多种应用开发,如:电子地图查询系统,娱乐游戏机等。本文在CSB226开发板上插入一块基于Prism2芯片组的CF接口的无线网卡,由于已经成功驱动了CF接口,所以只需要将无线接入点程序Host AP编译到ARM Linux内核中,再使用网桥工具将CSB226开发板自身的10MBit以太网和无线网络桥接起来,这个开发板就可以作为一台无线接入点工作了。
5.结论
Linux操作系统在嵌入式设备中应用越来越广泛。本文针对基于PXA255处理器的开发板进行了系统移植,阐述了移植中的关键技术,如:内核的修改、文件系统建立、设备驱动的移植,最后在开发板上实现了无线接入点。本文的移植过程对于其他类型微处理器上Linux的移植也具有参考价值