我并没有为arm体系结构的处理器移植uclinux操作系统,因为这方面的关键工作已经有人做完了。我只是让uclinux操作系统在恒坚ARM4510开发板上跑起来了。 一、 熟悉开发板硬件构成和基本工作原理
恒坚ARM4510开发板选用32位的高性能三星4510微控制器、SST公司2Mx16bits的FLASH和现代公司的两片8Mx16bits的 SDRAM,共同构成了基本嵌入式硬件系统,属典型的嵌入式设备开发板,而且外围实验用件、开发及接口电路较为齐全。恒坚开发板自带的集成开发环境,易学易用,作为嵌入式软件编译入门和熟悉开发板硬件构成,还是不错的。在windows环境下,安装恒坚集成开发环境。然后,先跑恒坚开发板配的流水灯实验程序。从程序中,可以体会到几点:
1、 嵌入式软件构成
嵌入式软件一般由一段汇编程序(init.s)和随后的C程序构成。汇编程序作为起始部分,被定位在0x0地址,这个地址是硬件系统上电后,首先执行的地址。汇编程序通过写微控制器的各个硬件寄存器,完成硬件的初始化,如配置SDRAM地址、数据线位数(8位、16位、32位)等,然后跳转到后面的C程序中运行。
2、 嵌入式硬件构成
软、硬件是相互关联的。虽然用放大镜查板子、万用表量电路,都是熟悉“硬”构成的基础。这方面,可以查一下微控制器的32位数据线是如何与两片SDRAM的数据线相连的;还有低16位数据线与FLASH的16位数据线是如何相连的。
通过软件编程,可以写数据到微控制器的寄存器中,以配置硬件结构、功能、性能等。比如,向微控制器的SDRAMCON0寄存器中写入 0x20040380,SDRAM的地址就映射在微控制器的存取地址区域0x1000000~0x2000000之间。如果再次向SDRAMCON0寄存器中写入0x10000380,则SDRAM的地址就映射到0x0~0x1000000之间了。同时配合改写FLASH(ROM)控制寄存器 ROMCON0的内容,可把FLASH由上电时的0x0地址,映射到0x1000000地址,这就是地址重映射(remap)原理。重映射的目的,是让程序能够在SDRAM中运行,而非FLASH中,其原因是多样的。
以上硬件相关内容,可参考《ARM应用系统开发详解──基于S3C4510B的系统设计》一书的“应用系统设计与调试”一章,还有现代公司的SDRAM芯片数据资料、SST公司的FLASH芯片数据资料等。
3、 地址重映射的实现
在跑马灯实验程序中增加代码,可以实现地址重映射,并让程序在FLASH和SDRAM中循环跑动起来。
在汇编部分(init.s)的BL C_Entry 语句后,插入如下代码:
ldr r0, =0x0 /* FLASH起始地址*/
ldr r1, =0x200000 /* FLASH大小2M */
ldr r2, =0x1000000 /*SDRAM起始地址*/ rom2ram_copy_loop: /* copy image to ram*/
ldr r3, [r0], #4 /*[r0]->r3, r0=r0+4*/
str r3, [r2], #4 /*r3->[r2], r2=r2+4*/
subs r1, r1, #4 /*r1=r1-4*/
bne rom2ram_copy_loop /*将整个FLASH中的内容,全部拷贝到SDRAM中*/ LDR r1, =rEXTDBWTH /*设置外围各芯片与微控制器连结的数据线宽度(位)*/
LDR r2, =rROMCON0_S /*设置FLASH(ROM)起始(0x1000000)、结束地址*/
LDR r3, =rROMCON1 /*设置第二片ROM,本系统没有,可忽略*/
LDR r4, =rROMCON2 /*同上*/
LDR r5, =rROMCON3 /*同上*/
LDR r6, =rROMCON4 /*同上*/
LDR r7, =rROMCON5 /*同上*/
LDR r8, =rSDRAMCON0_S /*设置SDRAM起始(0x0)、结束地址*/
LDR r9, =rSDRAMCON1 /*设置第二片SDRAM,本系统没有,可忽略*/
LDR r10,=rSDRAMCON2 /*同上*/
LDR r11,=rSDRAMCON3 /*同上*/
LDR r12,=rSREFEXTCON /*设置SDRAM刷新率及外部I/O组0的地址*/
LDR r0, =EXTDBWTH /*寄存器组的起始地址,0x3FF3010*/
STMIA r0, {r1-r12} /* remap![r1]->[r0], [r2]->[r0+4], [r3]->[r0+8]……*
/*把SDRAM的地址映射到0x0,FLASH则映射到0x1000000*/
BL C_Entry /*重映射后,再次循环走灯和闪烁*/
另外,还须更改C代码主程序C_Entry()中的内容如下:
{
//while(1) 不再进入死循环
//{
ledRun(10); //循环走灯10次
shineled(5); //闪烁5次
//}
}
用恒坚的集成编译环境编译并下载程序到开发板,观察同样的C程序在FLASH和SDRAM中运行时跑马灯的循环和闪烁速度是否不同。
恒坚开发板还配有几个程序,如串口通信实验程序,LCD显示控制实验程序。这些程序都不大,很经典,值得花些时间认真研究一下。
最后需要说明,集成开发环境多用于编译简单的程序,如单循环前后台式的、编程量不大的应用程序。如果要实现多任务下的复杂调度,又要能简化软件设计和充分利用微控制器的高性能,就要嵌入操作系统了。在引入uclinux操作系统后,一般改用命令行式的编译工具,如arm-elf-gcc等,它们运行在 Linux操作系统之上,而非windows操作系统了。
二、 学用Linux操作系统
因为免费和开源,在科研和开发领域,linux操作系统正在逐渐取代windows操作系统,成为个人计算机的主流操作系统。
1、 为(宿)主机安装linux操作系统
选择内核稳定的高版本linux操作系统,可以保证安装时对硬件设备的自动识别,更可保证以后编译和运行的可靠性。硬盘分区时,必须建立交换分区 (swap),其大小是主机内存的两倍;还要有一个ext3分区挂载在linux系统根目录(\)下,它至少要有3G;条件许可,还可以建立一个100M 大小的分区,挂载在启动目录(\boot)下。选择工作站方式安装linux系统即可。
2、 uclinux与linux的不同
uclinux源自linux,是对后者的裁减、精化,也有一些改动。后者多用于台式机,对硬件设备要求高。前者则多用于嵌入式设备中,毕竟嵌入式设备资源有限。
3、 其它虚拟操作系统
有些建立在windows操作系统之上的或并行的虚拟linux环境,如cygwin,VM等,但它们并不适合初次移植uclinux操作系统到嵌入式设备时选用。如果选用它们,就必须更改uclinux系统源代码中的多份Makefile文件内容,以适应编译时从标准linux操作系统到其仿真环境的变化。
三、 建立交叉编译环境
1、 体系结构的概念
大部分宿主机的cpu都是建立在X86体系结构上的,如intel或赛扬的cpu,也有其它体系结构的,但没有arm体系的,因为arm几乎是嵌入式设备专用的处理器体系结构了。三星4510微控制器是建立在arm体系结构之上的。体系结构的不同,确立了不同的指令系统,就像cpu使用不同的语言一样。无法想象英国人可以读懂俄文小说,同样,为X86体系的cpu编译的程序,也无法运行在arm体系结构的微控制器之中了。
宿主机上运行的linux 操作系统,是建立在X86体系结构上的。在linux操作系统上编译的程序,一般也是建立在X86体系上的。可以编写几个程序,用linux操作系统自带的编译工具gcc编译它们,如果没有语法错误,它们就都可以在宿主机上运行了。但要实现在宿主机上编写程序,编译后程序能在arm体系结构的嵌入式设备上运行,就需要一套特殊的“交叉”编译工具,如arm-elf-gcc等。所以,在linux操作系统的宿主机上编写程序,通过选用交叉编译工具arm- elf-gcc编译后,生成的可执行文件,就可以在arm体系结构的微控制器上运行了。这就是交叉编译的概念。
2、 建立交叉编译环境
通过引入arm-elf-gcc等交叉编译工具,可以在宿主机上建立交叉编译环境。这样,在宿主机上编译的程序,就可以在arm体系结构的嵌入式设备上运行了。恒坚开发板自带的文件arm-elf-tools-20030314.sh,只要在linux环境下执行它,就可以建立起完整的交叉编译环境。
四、 编译和下载uclinux操作系统
uclinux 操作系统已经被成功移植到许多微控制器上,其中也包括三星4510微控制器。移植后的uclinux操作系统源代码中含有微控制器外围电路的设置,如 SDRAM数据线的位数。有些嵌入式设备,同样是使用三星4510微控制器,却用一片现代公司的8Mx16bits的SDRAM,这样微控制器与 SDRAM的数据交换,就只用微控制器的低16位数据线。微控制器中的寄存器EXTDBWTH,用于配置每组(FLASH、SDRAM和外部I/O芯片等)的数据线的宽度。恒坚开发板上是用两块8Mx16bits的SDRAM拼成了32位数据线宽。
恒坚开发板自带一套移植后的和压缩了的 uclinux操作系统源代码文件uClinux-dist-20030522.tar.gz,把它拷贝到宿主机linux操作系统的/home目录下,进入/home目录,并用tar xzvf uClinux-dist-20030522.tar.gz命令解压缩源代码文件,产生/home目录下的 /uClinux-dist子目录,此目录中含有编译uclinux操作系统的全部源文件。把恒坚开发板自带的压缩的补丁文件uClinux-dist- patch.tar.gz拷贝到/uClinux-dist子目录下。进入/uClinux-dist子目录,并用tar xzvf uClinux- dist-patch.tar.gz命令解压缩补丁文件,可释放出两个文件:mkpatch和uClinux-dist-20030522- helloworld.patch,执行./ mkpatch,既可对uclinux操作系统的源代码打补丁。打补丁的根本原因,是为了修正源代码中的硬件参数设置,如原移植源代码是为一片SDRAM、16位数据线宽做的,而恒坚的板子上是两片SDRAM,并通过高、低16位数据线的组合,构成32位的数据线宽度。这就需要改变寄存器EXTDBWTH的赋值。还有原移植源代码是为8M字节的SDRAM作的,而恒坚板上是16M字节的SDRAM,这又要改变寄存器SDRAMCON0的赋值了。
打完补丁后,就可以在/uClinux-dist子目录下配置uclinux操作系统内核了。执行 make menuconfig,弹出的配置框中有四项内容。在第一项中配置设备(vendors)为Samsung/4510B,配置函数库为uC- lib,配置内核为linux-2.4.x。另三项可不动,保存后退出。然后顺序执行如下命令:make dep;make lib_only; make user_only;make romfs;make image;make。如果没有报告错误,在../uClinux- dist/linux-2.4.x/image子目录下,就会有三个文件。其中,image.ram是非压缩的uclinux操作系统内核,可以利用恒坚开发板自带的boot.bin(也就是一般所说的bootloader程序),通过网口传送到SDRAM中。这样,uclinux操作系统即可在 SDRAM中跑起来了。image.rom则是压缩的uclinux操作系统内核,并包含硬件相关的头文件等。利用恒坚的集成开发环境,可以下载 image.rom到开发板的FLASH中,下载需要很长的时间。再次上电后,uclinux操作系统就在开发板上跑起来了。当然,通过开发板串口与宿主机串口联接,在宿主机上建立控制台,是观察和操控开发板上uclinux操作系统的首要条件。
五、 遇到的问题和解决的办法
1、 曾经想用cygwin代替linux操作系统,花费了不少的时间,但没有成功。
2、 linux操作系统可以安装在大多数的微机上,但它无法识别我的一台三星显示器,那台机子上就一直没有再安装linux操作系统。我还有一台配有赛扬 500处理器的组装机,用它编译uclinux操作系统内核,有时会出现错误。有人说,linux操作系统对机器要求较高,所以我现在用一台标准配置的联想微机。
3、 由于我用的恒坚开发板上的FLASH芯片地址线17、18脚连焊了,我编译的内核文件image.rom,用恒坚的集成开发环境下载后,总无法从FLASH中运行起来。我先分析了uclinux操作系统的源代码,没有找到问题;又做了一块Jtag接口板,来替代恒坚的接口板,还是不行;用了其它的FLASH写工具,才把问题定位在FLASH芯片上,前后用了两周的时间,才解决了问题。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。