第uClinux在UPNETARM平台上的移植.ppt
《第uClinux在UPNETARM平台上的移植.ppt》由会员分享,可在线阅读,更多相关《第uClinux在UPNETARM平台上的移植.ppt(162页珍藏版)》请在三一办公上搜索。
1、第12章 uClinux在UP-NETARM3000平台上的移植,在Linux环境下,本章主要介绍了uClinux在UP-NETARM3000平台的移植过程。包括:uClinux源码下载方法和交叉编译工具的下载、生成方法。内核源码的修改、剪裁和编译过程。内核裁剪时的菜单选项的配置方法。内核及根文件系统的烧写过程。,12.1 UP-NETARM3000嵌入式教学开发平台介绍,UP-NETARM3000平台是博创兴业科技有限公司,依托北京航空航天大学开发的。适用于嵌入式教学和开发。目前已应用于清华大学、北京航空航天大学等多所高校。,该平台是基于S3C44B0X 处理器,可以运行uC/OS-II和u
2、Clinux的系统。它由核心模块和扩展模块组成。核心模块包括3C44B0 x嵌入式芯片、2MB线性引导Flash和8MB SDRAM;,扩展模块包括16MB非线性Flash、二个串口、一个USB口、一个JTAG通用接口、10M以太网口、触摸屏、17键键盘、320240STN彩色LCD、16M U盘、直流电机模块、步进电机模块、音频模块、CAN总线模块、A/D和D/A模块、LED显示器、IIC接口和FPGA模块。如图12-1所示。,图12-1 UPNETARM3000嵌入式教学开发平台,12.2 uClinux在UP-NETARM3000上的移植,所谓Linux移植就是把Linux操作系统针对具
3、体的目标平台做必要改写之后,安装到该目标平台使其正确的运行起来。这个概念目前在嵌入式开发领域讲的比较多。,其基本内容是:获取某一版本的Linux内核源码,根据具体目标平台对这源码进行必要的改写(主要是修改体系结构相关部分),然后添加一些外设的驱动,打造一款适合于自己目标平台(可以是嵌入式便携设备也可以是其它体系结构的PC机)的新操作系统,对该系统进行针对目标平台的交叉编译,生成一个内核映象文件,最后把该映象文件烧写(安装)到目标平台中。,而通常对Linux源码的改写工作难度较大,它要求不仅对Linux内核结构要非常熟悉,还要求对目标平台的硬件结构要非常熟悉。同时还要求对相关版本的汇编语言较熟悉
4、,因为与体系结构相关的部分源码往往是用汇编写的,所以这部分工作一般由目标平台提供商来完成。,比如说针对目前嵌入式系统中最流行的ARM平台,它的这部分工作就是由英国ARM公司的工程师完成的,我们所要做的就是从其网站上下载相关版本Linux内核的补丁(Patch)。把它打到目标平台的Linux内核上,再进行交叉编译就行。其基本过程如下(以Linux2.6.0为例):,1到ftp:/ftp.arm.linux.org.uk上下载Linux2.6.0内核及其关于ARM平台的补丁(如:Patch-2.6.0-rmk1.gz)。2给Linux2.6.0打补丁:zcat./patch-2.6.0-rmk1.
5、gz|patch p1(前面./表示补丁文件放在内核文件上一层目录)。,3准备交叉编译环境。交叉编译环境工具链一般包括binutils(含AS汇编器,LD链接器等),arm-gcc,glibc等。交叉编译环境的搭建也是个复杂的过程,后面我将做进一步介绍。有兴趣可以一起交流()。,4修改内核目录下的makefile文件,主要是以下几行:注释掉ARCH:=$(shell uname m|sed e s/i.86/i386/-e s/sun4u/sparc64/-e s/arm.*/arm/-e s/sa110/arm/)这一行;ARCH?改为 ARCH arm;,CROSS_COMPILE?=改为
6、 CROSS_COMPILE=你的交叉编译工具中arm-linux所在目录/arm-linux-。5此后就可以进行编译。,12.2.2 关于交叉编译环境,交叉编译环境的建立最重要的就是要有一个交叉编译器。所谓的交叉编译就是:利用运行在某机器上的编译器编译某个源程序生成在另一台机器上运行的目标代码的过程。编译器的生成依赖于相应的函数库,而这些函数库又得依靠编译器来编译,所以这里有个“蛋和鸡”的关系。,这里主要用到的编译器是arm-gcc,它是gcc的arm改版。目前Linux操作系统主要是以GCC模式进行移植的。GCC输出的是汇编语言程序,如果我们想要进一步编译成我们想要的机器代码,则还需要汇编
7、器等的协助。,GNU工具链中通常包含GNU Binutils,GNU GCC,GNU GLibc。Binutils中主要包含链接器ld和汇编器as。GNU GLibc提供了一个C库,使得系统能完成基本的系统调用及其它的一些函数调用。下面介绍一下GCC交叉编译器的生成过程。步骤如下:,1取得Binutils、GCC、Glibc的源码 可以到相关网站去获得,并把这三个文件解压到你自己的目录如:/toolchain/gcc,/toolchain/bu,/toolchain/glibc,2配置并编译Binutils,得到汇编器和连接器 在配置Binutils之前先把Linux内核中GCC所必需的头文件
8、拷到GCC可以找到的目录。如下操作:cp dr include/asm-arm/toolchain/gcc/arm-linux/include/asmcp dr include/linux/toolchain/gcc/arm-linux/include/linux,然后进入Binutils目录:./configure-target=arm-linux-prefix=/toolchain/bumake LANGUAGES=”C”make install,3配置并编译GCC源代码,生成GCC编译器 编译之前先修改gcc 的t-linux 文件,t-linux文件在好几个地方都有,我们要修改文件放在
9、gcc/config/arm目录下。在t-linux文件中的TARGET_LIBGCC2_CFLAGS后加上_gthr_posix_h和inhibit_libc操作如下:,进入gcc/config/arm目录 mv t-linux t-linux-orig/备份原来的t-linux文件 修改t-linux文件 把TARGET_LIBGCC2_CFLAGS=-fomit-frame-pointer fPIC改为:TARGET_LIBGCC2_CFLAGS=-fomit-frame-pointer-fPIC-Dinhibit_libc-D_gthr_posix_h(是行连接符号),进入GCC安装目
10、录进行编译操作如下:./configure-target=arm-linux-prefix=/toolchain/gcc-enable-languages=c-with-local-prefix=/toolchain/gcc/arm-linux,-without-headers(不编译头文件)-with-newlib-disable-sharedmakemake install这里首先生成的是C编译器。,4配置Glibc编译生成Glibc的C函数库 编译Glibc之前先要把编译器改为新的交叉编译器arm-linux-gcc,同时要指定编译所需要的头文件。操作如下:CC=arm-linux-gc
11、c AR=arm-linux-ar RANLIB=arm-linux-ranlib 然后进入Glibc的安装目录,进行配置如下:,./configure-host=arm-linux-prefix=/toolchain/gcc/arm-linux-enable-add-ons-with-headers=/toolchain/gcc/arm-linux/includemakemake install,4再次配置并编译GCC源代码,生成其它语言的编译器如:C等。恢复t-linux 文件 用备份的t-linux-bak 覆盖改动后的t-linux,命令如下:cp/toolchian/gcc/conf
12、ig/arm/t-linux-orig/toolchian/gcc/config/arm/t-linux,当然你也可以直接修改t-linux文件,把刚才加上去的_gthr_posix_h和inhibit_libc删去。不过推荐的做法是使用备份文件。这是一种更好的习惯。,重新编译./configure-target=arm-linux-prefix=/toolchian/gcc-enable-languages=c,c+-with-local-prefix=/toolchian/gcc/arm-linuxmake make install,这部分工作如果从头自己做是比较复杂的,而且你必需对你的硬
13、件平台的体系结构非常熟悉,所以我们通常从网上直接下载相关工具包。,12.2.3 修改uClinux内核源码,在完成交叉编译环境的建立之后,进入下一阶段,对uClinux内核的移植修改。uClinux的移植是个繁重的工作,其主要主要包含启动代码的修改,内核的链接及装入,参数传递,内核引导几个部分。,uClinux内核分为体系结构相关部分和体系结构无关部分。在Linux启动的第一阶段,内核与体系结构相关部分(arch目录下)首先执行,它会完成硬件寄存器设置,内存映射等初始化工作。然后把控制权转给内核中与系统结构无关部分。而在移植工作中要改动的代码主要集中在与体系结构相关部分。,在arch目录中可以
14、看到有许多子目录,它们往往是用芯片命名的,表示是针对该芯片体系结构的代码。为arm系列芯片编译内核,就应修改ARM目录下的相关文件。在ARM的子目录下可以找到一个boot目录,在boot下有一个init.S的文件。,这里init.S是用ARM汇编写成的。这个init.S就是引导uCLinux内核在Arm平台上启动的初始化代码。它定义了一个全局符号_start(默认的起始地址)。同时它也是整体内核二进制镜像的起始标志。,init.S主要完成以下功能:定义数据段、代码段、bbs(未初始化数据段)起始地址变量并对bbs段进行初始化。设置寄存器以初始化系统硬件。关闭中断。,初始化LCD显示。将数据段数
15、据复制到内存。跳转到内核起始函数start_kernel继续执行。对主寄存器的修改。,其源代码读者自己可以进行分析,而至于初始化设置的寄存器则要根据你的平台,参考相应的芯片手册。一般要做修改的寄存器有:片选组基地址寄存器,DRAM存储配置寄存器,DRAM片选寄存器,中断屏蔽寄存器等。此后代码会进入到entry.S继续执行,它会继续完成对中断向量表配置等一系列动作。,第一阶段的启动过程除了以上所说的之外,还要进行内核的链接与装入等工作。内核可执行文件是由许多链接在一起的目标文件组成的。以ELF为例,ELF文件有text(文本段)、data(数据段)和bbs等组成。,这些段又由链接脚本(Linke
16、r description)负责链接装入。链接脚本又有输入文件和输出文件。输出文件中输出段告诉链接器如何分配存储器。而输入文件的输入段则描述如何把输入文件与存储器映射。其形式如下:(输出文件),/*linux/arch/arm/boot/compressed/vmlinux.lds.in*Copyright(C)2000 Russell King*This program is free software;you can redistribute it and/or modify*it under the terms of the GNU General Public License vers
17、ion 2 as*published by the Free Software Foundation.*/,OUTPUT_ARCH(arm)/输出为ARM格式ENTRY(_start)/定义入口点SECTIONS.=LOAD_ADDR;/“.”表示当前计数器 _load_addr=.;.=TEXT_START;/文本段起始 _text=.;,.text:/把各个输入文件中文本段合并到此 _start=.;*(.start)*(.text)*(.fixup)*(.gnu.warning)*(.rodata),*(.rodata.*)*(.glue_7)*(.glue_7t)input_data=
18、.;arch/arm/boot/compressed/piggy.o input_data_end=.;.=ALIGN(4);,_etext=.;/文本段结束(以下各段类似)_got_start=.;.got:*(.got)_got_end=.;.got.plt:*(.got.plt).data:*(.data)_edata=.;,.=BSS_START;_bss_start=.;.bss:*(.bss)_end=.;.stack(NOLOAD):*(.stack),.stab 0:*(.stab).stabstr 0:*(.stabstr).stab.excl 0:*(.stab.excl)
19、.stab.exclstr 0:*(.stab.exclstr).stab.index 0:*(.stab.index).stab.indexstr 0:*(.stab.indexstr).comment 0:*(.comment),经过以上两个步骤,接下来要向内核传递参数并引导内核启动。前面的工作已经完成了初始化硬件寄存器、标示根设备和内存映射等工作。,其中启动代码以参数形式把DRAM和Flash数量(指定系统中可用页面的数目和文件系统大小)等信息传给内核。接下来完成设置陷阱、初始化中断、初始化计时器和初始化控制台等一系列操作,并使内核正确启动。,Linux移植过程中内容非常多,涉及的知识量
20、也很大,而且由于平台的不同和内核版本的不同所涉及的内容往往也有很大不同。所以以上给出内容也仅作为读者参考之用。,具体操作时还应收集相关平台及内核版本的详细资料,才能展开相应工作。下面以已经改造好的uClinux,针对UP-NETARM3000平台来讲解内核的裁减。,12.2.4 Linux内核裁减,Linux内核的裁剪与编译看上去是个挺简单的过程,只是对配置菜单的简单选择。但是内核配置菜单本身结构庞大,内容复杂。现在结合内核裁剪过程,了解配置各选项的作用。Linux内核的编译菜单都是通过Config.in经由不同脚本解释器产生.config。,它包括“make config”、“make me
21、nuconfig”和“make xconfig”等版本。“make config”以命令行方式进行配置,“make menuconfig”以菜单方式进行配置,且配置稳定可靠;“make xconfig”以基于图形库菜单方式进行配置,基于目前2.4.X版本的xconfig比较成熟稳定;基于2.6.X的xconfig菜单结构清晰,界面友好,但不够稳定。,所以考虑最大众化角度,以界面不够友好,但比较稳定的menuconfig为主进行介绍。在选择相应的配置时,有三种选择方式,它们分别代表的含义如下:Y-将该功能编译进内核 N-不将该功能编译进内核 M-将该功能编译成可以在需要时动态插入到内核中的模块,
22、make xconfig使用鼠标选择对应的选项,make menuconfig使用空格键进行选取。在每一个选项前的括号,可以是中括号、尖括号和圆括号。中括号里要么是空,要么是*;而尖括号里可以是空、*和M;而圆括号的内容是在所提供的几个选项中选择一项。,其中空表示不将该功能编译进内核,*表示将该功能编译进内核,M表示将该功能编译成可以在需要时动态插入到内核中的模块(注:其中有不少选项是目标板开发人员加的,对于陌生选项,自己不知道该选什么时建议使用默认值)。,下面我们来看看具体配置菜单,进入内核所在目录,键入make menuconfig你就会看到选项配置菜单。1Code maturity le
23、vel options代码成熟度选项,它又有子项:,(1)prompt for development and/or incomplete code/drivers 该选项是对那些还在测试阶段的代码、驱动模块等的支持。一般应该选这个选项,除非只是想使用LINUX中已经完全稳定的东西。但这样有时对系统性能影响挺大。,(2)prompt for obsolete code/drivers 该项用于对那些已经陈旧的被现有文件替代了的驱动程序和代码的支持,可以不选;除非你的机器配置比较旧,但那也会有不少问题。所以该项以基本不用,在新的版本中已被替换。,2loadable module support
24、动态加载模块支持选项,其子项有:(1)enable module support 支持模块加载功能,应该选上。,(2)set version information on all module symbols 该项用来支持跨内核版本的模块支持。即为某个版本的内核编译的模块可以在另一个版本的内核下使用,我们一般用不上,所以不选。,(3)kernel module loader 如果你启用这个选项,你可以通过kerneld程序的帮助在需要的时候自动载入或卸载那些可载入式的模块,我们一般会选上。,3system type 系统类型,主要是CPU类型以及与此相关的内容。该项下的子项比较多,内容也比较复
25、杂,无法对每个CPU都加以说明,就以开发平台作相应介绍,其他平台与此类似。,如果你是进行交叉编译,该项下的内容往往是经过相应目标平台开发人员修改的。主要是针对该平台的体系结构定义,这样可以优化系统性能。正因为目标平台的多样性,所以该项定义也常常是五花八门。,但开发人员一般会考虑到这些,事先设定好默认值。作为初学者按给出的默认选项就行。当然你也许想用一个原始的版本内核来建构针对你的平台的新内核。如果你的内核版本支持你目标平台所用的CPU,那你就选上它。,但不要选同系列中高于你所用的CPU型号,否则不支持。你也可以在Config.in或KConfig中修改该项以支持你的目标平台。当然其中还有一些较
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- uClinux UPNETARM 平台 移植
链接地址:https://www.31ppt.com/p-5159959.html