1.建立开发环境
    作为uClinux系统的移植和开发的主机最好使用Linux操作系统,如果选择Windows平台作为开发平台则需要Cygwin软件包的支持。在这里我们选用的开发平台是Fedora Core 2,内核版本为2.4.x。在进行uClinux的移植和开发之前,我们需要建立系统的交叉编译环境,因为做为主机我们使用的是IA32体系结构的处理器,而开发板我们才用的是ARM体系结构的处理器。ARM平台的交叉编译工具可以从uClinux的官方网站获得(www.uclinux.org)。在这里我们采用的是arm-elf-tools-20030314.sh,该文件是一个自解压文件,可以直接执行程序安装。
    #./arm-elf-tools-20030314.sh
    如果不能执行该文件,则需要修改一下文件的可执行属性
    #chmod 755 arm-elf-tools-20030314.sh
    然后再执行程序的安装。可执行文件按会被默认安装在/usr/local/bin目录下。

2.编译uClinux内核
    uClinux是一款支持无MMU单元的嵌入式操作系统,我们可以从其官方网站获取最新版本的内核文件(www.uclinux.org)。
    我们将下载的uClinux内核文件放入我们的工作目录(/home/jelly/kernel/),然后使用tar工具解压内核文件。
    $cd /home/jelly/kernel/
    $tar xvzf uClinux-dist-200xxxxx.tar.gz
    经过一段时间的解压后将在工作目录下会生成uClinux-dist文件夹。
    在编译内核之前我们首先要做的是配置内核,常用的配置方式有如下几种:
    make xconfig – X Windows图形界面的配置选项
    make menuconfig – Console图形界面的配置选项
    make config – 命令接口的配置选项
    在这里需要注意的是uClinux是不支持loadable modules的,因此应该取消对该模块的支持。

    $cd uClinux-dist/
    $make menuconfig

    配置你需要的选项,比如处理器类型,开发板类型,内核版本等。配置好之后选择Saving and Exiting保存退出。

    编译uClinux内核的常用选项有:
    make distclean
    该命令将清除以前编译时候产生的文件,包括.config文件,所有目标文件以及内核映象文件。

    make clean
    该命令与make distclean相似,也是清除之前编译时候产生的文件

    make dep 这个只需要在第一次编译的时候执行,为了是建立文件之间的依赖关系,make命令会根据这个依赖关系来确定哪些文件需要重新编译,哪些文件可以跳过。

    make lib_only
    编译uClibc库

    make user_only
    编译用户制定的应用程序,比如初始化进程init,bash,以及集成了很多常用工具的嵌入式软件包busybox。

    make romfs
    uClinux经常才用romfs(只读文件系统)来作为系统的根文件系统,所以首先需要将之前编译的很多应用程序以uClinux所需要的目录格式存放起来。比如将可执行文件放在bin目录下,将配置文件放在etc目录下。该命令执行后会在uClinux-dist目录下生成一个romfs的目录,并且将文件系统所需要的文件组织起来,以便之后生成fomfs的映象文件。

    make image
    生成romfs文件系统的映象文件,以及linux的映象文件。该linux的映象文件是elf格式的,是不能直接下载到开发板上执行的(里面包含了大量的调试信息,elf文件执行前的环境建立信息等内容。该文件可以使用arm-elf-objcopy工具来生成可以直接在RAM中执行的binary文件)。

    make linux
    执行该命令之后将生成linux内核文件。

    make zImage
    建立经过gzip算法压缩过的内核映象文件,通常zImage产生的内核映象文件无法超过512KB大小。

    make modules
    建立内核模块

    注:有些uClinux版本提供了更多的编译方式,比如make linux.bin。关于其他的编译方式可以参看内核源码目录里的Makefile文件。

    在介绍完常用的几个内核编译命令后,我们可以使用如下的几个命令来建立我们所需要的内核以及文件系统:
    make dep
    make clean
    make all

    这样在uClinux-dist/linux-2.x.x目录下会生成linux, System.map,在uClinux-dist/images/目录下会生成image.bin, linux.bin, image.ram, image.rom, romfs.img, linux.text, linux.data等文件。如果你编译过程中没有出现错误,但是没有我说的这些文件,你可以参看Makefile文件了解更多的东西。
    其中image.ram是直接可以下载到ram中执行的文件。在调试阶段我们就可以使用该文件。
    image.rom是一个zImage文件,可以自解压的内核,该文件需要少写到FLASH里,而不能直接放入RAM中执行。

3.uClinux内核建立过程
    建立内核首先是建立单独的内核模块和内核子系统,一旦这些建立好了之后将通过连接文件将多个文件连接在一起。该连接文件一般在arch/$(ARCH)/$(PLATFORM)/$(BOARD)/$(MODEL).ld。连接器使用该连接文件生成linux文件:
    LD -T (MODUEL).ld crt0_$(MODUEL).o [objs] -o linux
    连接文件定义了内核如何组织内存段。

    System.map文件是通过linux文件产生的,用于调试使用。通过该文件可以方便的确定函数的位置。该文件是通过如下方式产生:
    NM $(LINUX) | grep -v ‘\(compiled\)\|\(\.o$$\)\|\(a\)’ | sort > System.map

    linux.data文件是包含内核所有数据段的代码,是通过移除linux文件中所有只读段和其他不需要的段得到的,该文件可以通过arm-elf-objcopy来产生,如:
    OBJCOPY -O binary –remove-section=.romvec –remove-section=.text\
                      –remove-section=.ramvec –remove-section=.bss\
                      –remove-section.eram linux linux.data

    linux.text文件包含了所有文本段代码,是去除数据段后的代码
    OBJCOPY -O binary –remove-section=.ramvec –remove-section=.bss\
                      –remove-section-.data –remove-section=.eram\
                      –set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text

    linux.bin文件,是可以实际载入内存中执行的文件,他的建立是通过linux.text和linux.data两个文件连接得到的,如:
    cat linux.text linux.data > linux.bin
    该文件只是内核,并没有包含文件系统。我们可以使用如下方式将文件系统和内核文件连接起来生成image.bin映象文件:
    cat linux.bin romfs.img > image.bin

4.手工生成ROMFS文件系统
    建立ROMFS文件系统之前应该手工建立文件系统树,例如通常ROMFS包含如下目录:
    /bin /dev /etc /lib /proc /sbin /tmp /usr /var

    然后我们可以将交叉编译好的应用程序放入/bin目录中,之后使用genromfs工具来建立文件系统的映象,如:
    genromfs -v -V "ROM Disk" -f romfs.img -d romfs > romfs.map

    最后,可以与内核文件连接在一起,然后烧入Flash中。
    cat linux.bin romfs.img > image.bin

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1450065 

Advertisements