当前位置: 首页 > 工具软件 > uclinux > 使用案例 >

linux运行uclinux程序,uClinux的编译与运行详解

汪天宇
2023-12-01

按常规编译完成后应该生成image.bin   linux   linux.data   linux.text romfs.img这5个文件,不过我只有linux/boot.rom(=romfs.img),今天上网查了查它们的定义。

romfs.img:这个文件是通过tools/romfs-inst.sh脚本,生成romfs目录及其下面的文

件,然后通过genromfs程序打包成一个文件romfs.img。romfs.img既可以放在Flash中,也可以放在RAM中,但需要在编译内核

时在driver/block/blkmem.c里指定地址,以便内核找到。

linux.text:编译后的内核中text段,一般放在Flash中,只读。

linux.data:编译后的内核中data、init段,一般放在SDRAM中,读写。

image.rom:通常image.rom的文件大小要比image.ram小很多,这是因为image.rom是

一个压缩过的内核,前面加上一个小的解压程序负责把内核解压后搬到指定位置。这个文件可以直接烧进Flash中,当然也可以在RAM中运行。这个文件实际

上就是通常Linux生成的zImage文件。

image.ram:这个内核没有压缩过,而且必须在RAM里运行。所以需要通过板子上的Bootloader将它下

载到指定位置后开始执行。相对image.rom而言,从RAM里启动内核,则代码段和数据段都在RAM里面。这个文件是编译生成的ELF格式的

Linux内核,通过arm-elf-objcopy工具生成的二进制映像文件。可以这样形象的说:image.rom = gunzipprogram

+ gzipped(image.ram)。

boot.rom:其实就是uClinux编译完成后的文件images/romfs.img,可以看一下它就是一个连接。

image.bin:上面三个文件顺序连接而生成的,image.bin = linux.text + linux.data + romfs.img。

1.创建开发环境

首先需要编译的环境。建议最好使用Linux 作为开发平台,因为Linux 以及uClinux 的开发者们基本都是在Linux

下完成的开发。为了能够编译uClinux,我们需要下载uClinux 的编译器。这个文件可以在uClinux

的官方网站得到,也可以在论坛的客服中心下载。

官方的下载地址是:

http://www.uclinux.org/pub/uClinux/arm-elf-tools/arm-elf-tools-20040427.sh

虽然同为gcc 和binutils 工具,但是必须使用uClinux 发布的版本,因为这个gcc 和binutils

都是为了能够编译FLAT 格式的文件而订制的,另外也加入了ARM 对PIC(Position Independent

Code,位置无关代码)的支持。PIC 的支持是用来编译动态库或者XIP 模式的可执行文件。关于XIP 的介绍有一篇文章:http://www.ucdot.org/article.pl?sid=02/08/28/0434210

大家可以了解一下XIP。但是由于XIP 并不是很稳定,所以在我们发布的uClinux

版本中并没有使用这个技术。然后,将下载得到的文件,是一个sh 文件。这是一个自解压的文件(就好比Windows下面的自解压zip 或者rar

一样)。为了能够运行,我们需要:

./arm-elf-tools-20040427.sh

这样如果不能运行的话,那应该使用下面的命令:

chmod u+x arm-elf-tools-20040427.sh(使之可执行)

./arm-elf-tools-20040427.sh

得到了编译环境,就可以编译源代码了。当然,首先要把代码解压缩到你的目录下面:

tar xjvf uClinux-dist-20060803.tar.bz2

它会把全部的文件解压缩到uClinux-dist 的目录下。然后进入目录

cd uClinux-dist

2.编译uClinux

对uClinux 进行配置。那是通过make menuconfig

或者make xconfig 来实现的。对于编译uClinux,不能简单地通过make

来实现。我们需要有一些特定的步骤才能保证编译的正确。这是因为uClinux

所需要支持的硬件平台太多了,不能考虑的很周到。为了编译最后得到的镜像文件,我们需要linux 的内核以及romfs。对于GDB/ARMulator的移植来说,romfs 是被编译到内核里面去的。因此,在编译内核前需要一个romfs。为了得到romfs 的image,我们又需要编译用户的应用程序。而为了编译用户的应用程序,我们又需要编译C 运行库,这里我们用的C 运行库是uClibc。根据上面的分析,我们编译uClinux 的步骤如下:make dep    这个仅仅是在第一次编译的时候需要,以后就不用了,为的是在编译的时候知道文件之间的依赖关系,在进行了多次得编译后,make 会根据这个依赖关系来确定哪些文件需要重新编译、哪些文件可以跳过)。

make lib_only

编译uClibc。以后我们编译用户程序的时候需要这个运行库,在运行这步时,采用uC-libc出错,但发现有些人却用的是这个,没问题,不知为何。

make user_only

编译用户的应用程序,包括初始化进程init,和用户交互的bash,以及集成了很多程序的busybox(这样对一个嵌入式系统来说可以减少存放的空

间,因为不同的程序共用了一套C 运行库),还有一些服务,如boa(一个在嵌入式领域用的很多的Web 服务器)和telnetd(telnet

服务器,我们可以通过网络来登录我们的uClinux 而不一定使用串口)。

make romfs(容易出错,见UC移植)

在用户程序编译结束后,因为我们用到的是romfs(一种轻量的、只读的文件系统)作为uClinux

的根文件系统,所以首先需要把上一步编译的很多应用程序以uClinux 所需要的目录格式存放起来。原来的程序是分散在user

目录下,现在例如可执行文件需要放到bin目录、配置文件放在etc 目录下..这些事就是make romfs 所做的。它会在uClinux

的目录下生成一个romfs 目录并且把user 目录下的文件、以及vendors 目录下特定系统所需要的文件(我们的vendors

目录是vendors/ARMlator/ARMulator组织起来,以便下面生成romfs 的单个镜像所用。

make image(容易出错)

它的作用有2 个,一个是生成romfs 的镜像文件,另一个是生成Linux 的镜像。因为原来的Linux 编译出来是elf

格式的,不能直接用于下载或者编译(不过那个文件也是需要的,因为如果你需要,那个elf

格式的内核文件里面可以包含调试的信息)。因此在这个时候由于还没有编译过Linux,因此在执行这一步的时候会报错。但是没有关系,因为我们在这里需要

的仅仅是romfs 的镜像,以便在下面编译Linxu 内核的时候使用。

make linux

(可能会出现error:cannot open romfs.o,其实这个文件已经有了,在linux-2.4.x/romfs/下,copy到uC下就可以了)

有了romfs 的镜像我们就可以编译Linux 了。因为我们的romfs 是嵌入到linux 内核中去了,所以在编译Linux 内核的时候就要一个romfs.o 文件。这个文件是由上面的make image生成的。

make image

(可能images/下只有一个boot.rom,我就是,其实这个文件就是romfs.img啦,链接一下,ln -s boot.rom romfs.img)

这里再一次make image 就是为了得到uClinux 的可执行文件的镜像了。执行了这一步之后,就会在images 目录下找到3

个文件:image.ram,image.rom,romfs.img。其中,image.ram和image.rom

就是我们需要的镜像文件。这个在下面“使用uClinux”会提到。为了方便起见,在uClinux-dist

目录下有两个文件:build_first.sh 和build_final.sh 先执行build_first.sh

再执行build_final.sh 就可以得到所需的镜像文件。之所以没有把两个合并,是因为第一次使用make image 会出错。

3.使用uClinux

上面我们提到了两个文件:image.ram 和image.rom。其中,image.ram 是直接下载到RAM

执行的文件。如果你还处于调试阶段,那么就没有必要把文件烧写到FLASH 里面。这个时候我们可以使用image.ram。在开发板运行BIOS

的情况下,使用:

netrun

将文件下载到RAM 并且自动执行。具体可以参考BIOS 的教程。

对于image.rom 来说,它是一个zImage

文件,也就是自解压的内核。由于它使用了gzip将内核压缩过,所以可以减小文件的大小。这个image 应该烧写到FLASH 的0x10000

的位置,而不能直接下载到RAM 并执行。在开发板运行了uClinux 之后,我们可以通过串口看到很多输出,但是最后可以看到

Welcome to

____ _ _

/ __| ||_|

_ _| | | | _ ____ _ _ _ _

| | | | | | || | _ \| | | |\ \/ /

| |_| | |__| || | | | | |_| |/ \

| ___\____|_||_|_| |_|\____|\_/\_/

| |

|_|

Execution Finished, Exiting

Sash command shell (version 1.1.1)

/>

这样就表明你的uClinux 正常启动了。这时候可以输入一些命令,例如:

/> ls -l

drwxr-xr-x 1 0 0 32 Jan 1 00:00 bin

drwxr-xr-x 1 0 0 32 Jan 1 00:00 dev

drwxr-xr-x 1 0 0 32 Jan 1 00:00 etc

drwxr-xr-x 1 0 0 32 Jan 1 00:00 home

drwxr-xr-x 1 0 0 32 Jan 1 00:00 lib

drwxr-xr-x 1 0 0 32 Jan 1 00:00 mnt

dr-xr-xr-x 16 0 0 0 Jan 1 00:00 proc

lrwxrwxrwx 1 0 0 97 Jan 1 00:00 sbin -> /bin

lrwxrwxrwx 1 0 0 105 Jan 1 00:00 tmp -> /var/tmp

drwxr-xr-x 1 0 0 32 Jan 1 00:00 usr

drwxr-xr-x 8 0 0 1024 Jan 1 00:00 var

/>

ls 命令可以列出当前目录下的文件,-l 参数可以列出更详细的信息。

/> cat /proc/meminfo

total: used: free: shared: buffers: cached:

Mem: 14630912 2199552 12431360 0 499712 507904

Swap: 0 0 0

MemTotal: 14288 kB

MemFree: 12140 kB

MemShared: 0 kB

Buffers: 488 kB

Cached: 496 kB

SwapCached: 0 kB

Active: 744 kB

Inactive: 240 kB

HighTotal: 0 kB

HighFree: 0 kB

LowTotal: 14288 kB

LowFree: 12140 kB

SwapTotal: 0 kB

SwapFree: 0 kB

/>

cat 可以将一个文件显示出来,这里的/proc/meminfo 表示内存的信息。您还可以看看

proc 目录下有些什么文件并且把他们显示出来看看

/> ps

PID PORT STAT SIZE SHARED %CPU COMMAND

1 S 134K 0K 0.1 init

2 S 0K 0K 0.0 keventd

3 S 0K 0K 0.0 ksoftirqd_CPU0

4 S 0K 0K 0.0 kswapd

5 S 0K 0K 0.0 bdflush

6 S 0K 0K 0.0 kupdated

15 S0 R 136K 0K 0.0 /bin/sh

16 S 70K 0K 0.0 /bin/inetd

17 S 264K 0K 0.0 /bin/boa

/>

ps 命令列出当前的进程的情况

在上面ps 的输出结果我们可以但到里面有boa,这就是我们的Web 服务器。另外,telnetd

是通过inetd 来启动的。

先来看一下boa。我们在主机的浏览器输入http://192.168.111.100

就应该看见一个默认的页面:

然后我们也可以通过telnet 来访问我们的uClinux 机器:

在主机使用Telnet 工具登录到uClinux(IP 地址上面有了,是192.168.111.100)

它会要你登录,选择用户名root,密码为空,就可以进去了。

就如下图所示:

如果这时候用ps 查看的话,就会发现多出来了2 个进程:

PID PORT STAT SIZE SHARED %CPU COMMAND

1 S 134K 0K 0.0 init

2 S 0K 0K 0.0 keventd

3 S 0K 0K 0.0 ksoftirqd_CPU0

4 S 0K 0K 0.0 kswapd

5 S 0K 0K 0.0 bdflush

6 S 0K 0K 0.0 kupdated

15 S0 R 140K 0K 0.0 /bin/sh

16 S 70K 0K 0.0 /bin/inetd

17 S 268K 0K 0.0 /bin/boa

19 S 74K 0K 0.0 /bin/telnetd

20 p0 S 134K 0K 0.0 sh

下面的第19、20 号进程就是新的。也就是和telnet 有关的两个进程

 类似资料: