历史上的今天
返回首页

历史上的今天

今天是:2025年08月13日(星期三)

正在发生

2020年08月13日 | Linux向目标系统AT91RM9200的移植方法与应用优势分析

2020-08-13 来源:elecfans

1.引言

目前,在嵌入式系统里基于ARM微核的嵌入式处理器以其功耗低,功能强大的优点已经成为市场的主流。与此同时,在网络上发展起来的Linux操作系统,以其功能强大,开放源代码,支持硬件种类众多的特点,越来越受到人们的青睐。然而如何把Linux操作系统移植到ARM平台上却成了一个重点,也是一个难点问题。

Linux向目标系统AT91RM9200的移植方法与应用优势分析

嵌入式Linux系统包括引导程序(Bootloader),内核(kernel)和根文件系统三个部分,其开发流程如图1所示:嵌入式Linux 移植到特定的硬件平台上,一般需要以下五个步骤:

(1)前期准备包括从网站上下载嵌入式Linux的源码包, 搭建交叉编译开发环境,配置主机的开发环境等

(2)配置Bootloader,并将其烧写到目标平台的Flash上,使其能正常的启动内核;(3)配置和编译Linux内核,首先要对源码进行一定的修改, 并将其移植到目标平台上,然后再根据自己的硬件资源进行裁减,使内核达到最优;

(4)制作RAMDISK来挂接Linux的根文件系统,并在 RAMDISK上添加自己的应用程序;(5)部署Linux系统使目标板脱离交叉开发环境,直接在目标机上本地启动运行。本文就将根据实际项目开发中一个 ARM构架的嵌入式系统为例,阐述如何移植Linux到AT91RM9200的ARM平台上。

Linux向目标系统AT91RM9200的移植方法与应用优势分析

2.建立交叉编译环境

一般而言,直接在移植的目标硬件平台上编写和调试Linux比较困难,目前一般采用的办法是首先在通用计算机上编写程序,然后通过交叉编译生成目标平台上可以运行的二进制代码格式,最后再下载到目标平台上的特定位置上运行。


移植前需要在宿主机上建立如图2所示的ARM的交叉编译环境,建立ARM的交叉编译环境主要用到的开发工具有: binutils、gcc、glibc,其中 binutils是二进制文件的处理工具; gcc是编译工具, 用来编译内核代码的工具; glibc 是链接和运行库。社区的开发者和一些芯片厂商已经编译出了常用体系结构的工具链,使用这些工具链,可以大大减少工作量。交叉编译工具的安装步骤如下: 

(1)从官方站点下载cross-2.95.3.tar.bz2;

(2)在usr/local/arm下解压:#tar -jxvf cross-2.95.3.tar.bz2;

(3)在/etc/bashrc文件中修改PATH环境变量,加入export PATH=/usr/local/arm/2.95.3/bin:$PATH。


3. ARM Linux系统的开发

3.1 Linux启动代码Bootloader的移植

Bootloader是在操作系统内核运行之前运行的一段小程序。这段程序完成硬件的初始化和建立内存空间的映射图等重要工作,为内核的启动创建正确的环境,并最终启动内核,Bootloader在Linux嵌入式系统中所处的层次位置如图3所示。Bootloader的实现依赖于CPU的体系结构,大多数的Bootloader都分为stage 1和stage 2两大部分,图4为两阶段Bootloader的结构框图。依赖于CPU体系结构的代码,如设备初始化代码等,通常都放在stage 1,而且用汇编语言实现。而stage 2则通常用C语言实现,这样可以实现复杂功能,而且有更好的可读性和移植性。

Linux向目标系统AT91RM9200的移植方法与应用优势分析

目前基于嵌入式系统的Bootloader版本很多,如Blob、Redboot、Vivi和U-Boot等,下面就以现在最流行的U-Boot为例,详细介绍如何将它移植到自己的目标板上。U-boot移植主要步骤如下:


首先基于自己的目标板的硬件资源,修改或添加U-Boot源代码的board/at91rm9200目录中如下源码文件:

(1)重写FLASH的设备控制程序flash.c , U-Boot读、写和删除Flash设备的源代码文件。由于在不同目标板中FLASH存储器种类各不相同,参照自己flash的datasheet重写 flash的设备控制程序flash.c,该程序完成的功能包括Flash初始化、打印Flash信息、Flash擦除和Flash写入等操作。

(2)添加memsetup.s。该汇编源码文件初始化时钟、SMC控制器和SDRAM控制器。(3)添加网卡芯片DM9161E的设备控制程序dm9161.c 和dm9161.h,程序。

(4)修改Makefile文件。对上述修改或添加的源代码文件编译后,在Makefile里面主要做如下修改: OBJS :=at91rm9200dk.c at45.o dm9161.o flash.o SOBJS:=memsetup.o

(5) U-Boot.lds ,设置U-boot中各个目标文件的连接地址,基本不做修改。

(6)config.mk。根据目标板的一级boot来修改,修改后TEXT BASE=0x21f00000。


其次,修改目录include/configs的头文件at91rm9200dk.h,根据目标板的资源配置,修改内容包括CPU ,系统时钟、RAM 、Flash等配里信息以及内存映射相关参数。该头文件还定义了U-Boot的一些环境变量和内核启动参数。可在U-Boot启动后通过setenv和 saveenv命令修改。U-Boot-1.1.2版本对at91rm9200处理器提供良好的支持,因此对于目录CPU at91rm9200中的源码基本不做修改。在U-Boot-1.1.2的Makefile中加入如下代码:

at91rm9200dk_config: unconfig@/mkconfig $(@: _config=) arm at91rm9200 at91rm9200dk


其中“arm”是CPU的种类,at91rm9200是ARM CPU对应的代码目录,at91rm9200dk是目标板对应的目录。由于交叉编译器安装在目录/usr/local/arm,应把环境变量 CROSS_COMPILE设置成相应路径:CROSS_COMPILE=/usr/local/arm/2.95.3 /bin/arm-linux-

最后,调试U-Boot源代码,直到U-Boot在开发板上能正常启动,调试成功后,烧写U-Boot到FLASH,烧写完成后,复位目标板,串口终端就显示U-Boot的启动信息。


3.2 Linux内核的移植、配置和编译

Linux向目标系统AT91RM9200的移植方法与应用优势分析

标准Linux内核相对于资源受限的嵌入式系统来说是过于庞大,整个代码分布如图5所示,因此要将其移植到嵌入式系统上,就需要将Linux内核根据目标平台的情况进行剪裁、配置,该目标板的主要硬件资源如图6所示。和ARM体系结构相关的代码都放在arch/arm/以及include/asm-arm/目录下,将linux移植到ARM平台上,主要修改这两个目录下的代码。要想使linux内核应用于自己的ARM平台AT91RM9200上,必须对内核的源代码做一定的修改,主要修改部分如下:

(1) 修改根目录下的Makefile文件,确认ARCH和CROSS_COMPILE的定义:ARCH :=arm; CROSS_COMPILE :=arm-linux- 

(2)修改arch目录下的Makefile文件,根据自己的电路设置TEXTADDR变量,TEXTADDR决定内核起始运行地址,即 image.ram应下载的地址。

(3)修改arch目录下的config.in 文件,添加CONFIG_ARCH_AT91RM9200自选项,config文件决定了menuconfig菜单的内容,把使用的平台加在需要的地方,这样在配置linux内核时就能够选择是否支你的平台了。

(4)修改arch/arm/boot目录下的Makefile文件,根据自己的电路设置ZTEXTADDR和ZRELADDR, ZTEXTADDR和ZRELADDR分别是自解压代码的起始地址和内核解压后代码输出起始地址。

(5)修改arch/arm/boot /compressed目录下的Makefile文件,加入head-at91rm9200.S 

(6)修改arch/arm/kernel目录下的Makefile文件,增加AT91RM9200的支持,同时在 debug-armv.S中加入关闭全部外围设备,保证系统正常运行的代码,在entry-armv.S中加入关于CPU中断处理部分的代码。

(7)修改 arch/arm目录下的mm-armv.c文件,将init_maps-》bufferable=0改为init_maps-》 bufferable=1;


当然,一些大的芯片开发商在发行芯片的同时,针对自己芯片的体系结构对linux内核作了一些补丁。实验中使用的是针对AT91RM9200体系结构的补丁patch-2.4.19-rmk7给标准内核源代码打上补丁后,该内核就可应用于AT91RM9200了,这样可以大大减少开发的工作量。


移植之后要做的工作就是编译内核,要想编译适合自己工程中需要的内核,首先要对内核进行配置,常用的配置命令有:make config;make oldconfig;make menuconfig;make xconfig;make defconfig;Linux内核包允许用户对其各类功能逐项配置,在配置时, 大部分选项可以使用其缺省值, 只有小部分需要根据用户不同需要选择。选择的原则是将与内核其它部分关系较远部分且不经常使用的部分功能代码编译成为可加载模块, 有利于减小内核的长度, 减小内核消耗的内存,不需要的功能就不要选, 与内核紧密且经常使用的部分功能代码直接编译到内核中。主要是进行以下几项配置: 

(1)选择处理器类型;

(2)选择板级支持;

(3)选择对RAMDISK支持、对设备驱动的支持以及对文件系统的支持。在配置工作完成后, 就可以进行内核编译。


编译内核有压缩方式和非压缩两种方式。非压缩方式使用make vmlinux来编译内核,或者直接运行make命令。压缩方式用make bzImage来编译内核。编译成功后会在arch/arm/boot目录中生成内核的镜像,此镜像下载到flash中就可以通过bootloader引导。具体的编译步骤如下:

(1) 进入打上补丁修改好的内核源代码目录下,执行make mrproper;make clean这两条指令,将源代码清理干净(防止以前编译产生的“垃圾”干扰)。

(2)执行make at91rm9200dk_config,使源代码按照AT91RM9200体系结构来配置。 (3)执行make o1dconfig(保存原编译配置)

(4)执行make menuconfig进入内核编译前配置界面,进行配置。

(5)执行make dep声称编译要用的依赖文件。

(6)执行make zImage生成内核镜像。


3.3 文件系统的移植

linux采用文件系统组织系统中的文件和设备,为设备和用户程序提供统一接口。linux要启动起来还需要有根文件系统。根文件系统的作用是存放各种工具(如Linux命令)、应用程序、必需的链接库等等。通常用busybox来制作根文件系统,在busybox中包含一百多种Linux上标准的工具程序, 而这些工具程序仅需几百k空间。busybox使用非常方便, 只要建立一个符号连接即可, 用户可以通过配置Config.h 和Makefile文件来定制busybox。将busybox复制到bin目录中,分别使用ln-s 建立每一个命令的符号连接。但应该注意的是busybox需要glibc支持(如果使用静态连接则不需要glibc 库文件),因此还需要将运行busybox所需的库文件copy到lib目录中, 并建立符号连接。到此为止, ARM Linux 的根文件系统就已经建立起来了。


ARM Linux采用RAMDISK的方式来装载根文件系统,所以在运行内核之前,需要先制作RAMDISK,将必须的文件和设备加人到RAMDISK中。内核启动后,会从指定地址去读取根文件系统,这里我们使用RAMDISK在内存中虚拟一个磁盘,具体方法如下:

(1)首先创建一个2048k的虚拟磁盘,文件名为initrd.img:# dd if= dev/zero of=initrd.img bs= lk count= 2048 

(2)将该虚拟磁盘文件格式化成Ext2格式:# mkfs ext2 -c initrd.img这就生成了一个支持Ext2文件系统的ramdisk 

(3)mount这个文件系统到/tmp下,# mount -o loop -t ext2 initrd.img /tmp 

(4)向/tmp中添加linux启动必须的文件和设备。 # cd /tmp; # mkdir bin dev etc lib mnt proc sbin sys usr 以上这几个程序和设备是启动Linux必须的,这样得到的ramdisk大约400k 

(5)创建设备节点,添加相应的程序,将已经订制好的一个文件系统全部复制过来。# cp –a myfs/* /tmp 

(6)压缩映像,把loop设备卸载下来,然后用gzip命令把映像压缩一下。# umount /tmp ; #gzip –best –c initrd.img 》 initrd.img.gz现在我们就得到了一个压缩的RAMDISK映像initrd.img.gz制作好了。

Linux向目标系统AT91RM9200的移植方法与应用优势分析

4. 内核的下载和执行

要想使目标板的Linux系统脱离交叉开发环境,直接在目标机上本地启动运行,必须通过U-boot将U-boot映像,内核映像和RAMDISK 映像烧写到FLASH中,因为使用U-boot引导程序需要使用U-boot格式的内核映像和RAMDISK映像,可以通过以下命令来实现:

($U-BOOT-PATH)/tools /mkimage -A arm -O linux -T kernel -C gzip –a 0x20008000 -e 0x20008000 –n “linux-2.4.19”-d linux.bin.gz uImage

($U-BOOT-PATH)/tools/mkimage-A arm -O linux -T ramdisk -C gzip –a 0x21100000 -e 0x21100000 –n “RAMDISK”-d ramdisk.bin ramdisk

通过U-boot将uImage和ramdisk烧写到flash相应的分区中去,烧写到flash相应分区的地址如图7所示:烧写完毕后设置u- boot的环境变量,让系统自动启动,系统复位后,Linux系统就可以完全自动从本地flash启动了,启动后,进行地址映射,u-boot会把u- boot压缩映像,kernel压缩映像,ramdisk压缩映像全部拷贝到SDRAM的相应地址,SDRAM的映射地址如图8所示,这时Linux系统完全在SDRAM中运行了,Linux系统真正启动起来了。


5. 总结

本文根据一个特定的目标平台,结合AT91RM9200的开发经验,详细介绍了将Linux移植到ARM构建的嵌入式系统上的主要技术和整个流程,实现了Linux 向目标系统AT91RM9200的移植,移植后的操作系统在目标板上运行稳定,并且可以根据实际需要编写相应的控制程序,将其应用于实际工业控制中。掌握这些技术,对于开发嵌入式系统十分重要,对开发其他类型的嵌入式系统同样具有参考意义。


本论文作者创新点:从软件与硬件的相互关系, 硬件对软件的制约、硬件对软件的支持这个角度对裁减和移植进行了分析,同时在Bootloader(启动代码)的移植,Kernel(内核)的裁减和移植过程中,把代码分成了两部分,一部分是和硬件相关的部分,一部分是和硬件无关的部分,这样做不仅思路清晰,而且可以大大减少工作量。

推荐阅读

史海拾趣

BAHCO公司的发展小趣事

在市场竞争日益激烈的背景下,BAHCO选择了与同样拥有悠久历史的美国Snap-on公司进行合作。这次强强联合不仅加强了双方在技术、市场等方面的互补优势,更为BAHCO打开了更广阔的市场空间。通过Snap-on的全球销售网络,BAHCO的产品得以进入更多国家和地区,进一步提升了公司的品牌影响力和市场竞争力。

Hendon Semiconductors公司的发展小趣事

Hendon Semiconductors在能源管理和照明控制领域也有着显著的成就。公司开发了一系列高效、可靠的能源管理解决方案和照明控制产品,广泛应用于智能家居、商业建筑和工业自动化等领域。这些解决方案不仅帮助客户降低了能耗和运营成本,还提高了能源使用效率和环境可持续性。通过不断创新和优化产品设计,Hendon Semiconductors在能源管理和照明控制市场上赢得了广泛的认可。

风华邦科(FH-BK)公司的发展小趣事

在电子科技领域,FlyWin集团不断投入研发资源,致力于新技术的开发与应用。公司成立了专门的研发团队,专注于人工智能、物联网等前沿技术的探索。通过不断的技术创新,FlyWin成功推出了一系列具有自主知识产权的电子产品,如智能传感器、物联网解决方案等。这些产品不仅提升了公司的市场竞争力,也为公司的长远发展提供了强大的技术支撑。

Bce Sud公司的发展小趣事

面对市场的不断变化和消费者需求的日益多样化,Bce Sud始终坚持创新驱动的发展理念。公司不断推出新产品,从半导体芯片拓展到传感器、集成电路等领域,产品线日益丰富。这些创新产品不仅提升了公司的市场竞争力,也为消费者带来了更多选择。

Ceramics公司的发展小趣事

某家名为“创新陶瓷”的Ceramics公司,通过不断研发新技术,成功打破了传统陶瓷材料在电子领域的应用限制。该公司推出了一款具有高热导率、低电阻率的陶瓷基板,显著提高了电子设备的性能稳定性。这一创新不仅赢得了市场的广泛认可,还吸引了多家知名电子厂商的合作意向。创新陶瓷通过持续的技术创新,逐渐在电子行业树立了领先地位。

American Custom Components公司的发展小趣事

American Custom Components公司自创立之初,就致力于电子元器件的创新研发。在一次技术研讨会上,公司的研发团队发现了一种新型的半导体材料,具有出色的导电性和稳定性。经过数月的实验和验证,团队成功地将这种材料应用于新产品中,推出了一款性能卓越的集成电路。这一创新技术不仅提升了公司的产品质量,还赢得了市场的广泛认可,为公司的发展奠定了坚实基础。

问答坊 | AI 解惑

自制简易热风焊台

现代电子产品广泛采用表面焊接技术,这给维修人员拆卸元器件带来不便。特别是拆卸多引脚芯片和塑封无引脚芯片,更使无专用工具的维修人员感到无从下手。   当然,采用热风焊台,可使上述难题迎刃而解。但是,一台进口热风焊台价格昂贵,国产的热 ...…

查看全部问答>

可以遛狗的跑步机

日本的游戏机真是五花八门,时不时让人大跌眼镜。想来也不错,这样的虚拟宠物,省去了养宠物的烦心处,只给留下快乐的感觉。 只是这样的机器,说是可以遛狗,到底遛的是谁,还真捉摸不清。 这是一个非常复杂的哲学问题。 庄周梦为蝴蝶,庄周 ...…

查看全部问答>

EVC 提示错误 one or more file from the emulator for windows ce is missing.please ret

各位大虾们,帮帮菜鸟吧 刚装EVC,新建一工程编译后没问题,但出现报错 one or more file from the emulator for windows ce is missing.please retinstall emulator for window ce and try again。是什么意思啊?我重装好几次也是这样啊,难道与 ...…

查看全部问答>

wince audio device 开发求助

前断时间把wince上的usb VIDEO device做好了(是slave的不是host),现在老板又需要做USB AUDIO DEVICE. USB部分已经正常能够发送数据,在电脑上录音设备也能录到声音。但是要真正实现把CE设备的声音通过USB传到电脑上来播放还必须要去修改AUDIO驱 ...…

查看全部问答>

怎么从/PROC/DEVICES中得到动态主设备号?脚本怎么样写,应该写在哪个文件里,怎么样在linux启动时运行这个脚本?谢谢!

怎么从/PROC/DEVICES中得到动态主设备号?脚本怎么样写,应该写在哪个文件里,怎么样在linux启动时运行这个脚本?谢谢!…

查看全部问答>

TI 官网已发布 Cortex-M4 和添加多款新一代 Cortex-M3 MCU

刚打开 TI 网站,发现有陌生的 LM3S 出现。TI 已正式发布了 Cortex-M4 和新一代的 Cortex 产品。除了 3000 系列之外,其它系列均有新成员加入。M3 新成员主要特点是 FLASH 和 RAM 更大了,ADC 分辨率提高了 12 bit.M4 的产品不用多说了,继续关注中 ...…

查看全部问答>

MC9S08QG8单片机实现单位时间捕获脉冲次数计数

最近正在做玩具智能车,不可避免的要用到单片机的捕获功能。 现想通过MC9S08QG8单片机实现单位时间捕获脉冲次数计数,来计算小车的速度。 问题卡在了捕获功能的实现上。   所用单片机:MC9S08QG8     8位机 实现功能 ...…

查看全部问答>

MSP430 ADC12 使用P6.1没有反应啊!很急啊 谢谢

/********************************************************* 程序功能:将ADC对P6.1端口电压的转换结果按转换数据在液晶上显示 **********************************************************/ #include #include \"allfunc.h\" #include \" ...…

查看全部问答>

ADI总结的放大器设计技术和放大器工艺

箝位放大器 箝位放大器允许设计人员指定高(VCH)和低(VCL)输出箝位电压,以使输出信号箝位在特定电平。与传统的输出箝位器件相比,ADI公司独特的CLAMPIN™输入箝位架构显著改善了箝位性能,箝位区的箝位误差和失真极小。 共模线性化放大器 ...…

查看全部问答>

Z-stack中的组播问题讨论

在调试Z-stack 2007的协议栈里的SampleApp的例子中发现,用户事件初始化函数SampleApp_Init中协调器和终端都加入到了group 1了。我操作终端按键K1,协调器能收到数据。但是我操作协调器的按键K1,终端却不能收到数据。这是为什么呢  难道 ...…

查看全部问答>