导航:首页 > 编程大全 > uclinux编译工具

uclinux编译工具

发布时间:2025-02-05 14:07:54

A. uclinux和linux的区别

Linux是一种很受欢迎的操作系统,它与UNIX系统兼容,开放源代码。它原本被设计为桌面系统,现在广内泛应容用于服务器领域。而更大的影响在于它正逐渐的应用于嵌入式设备。uClinux正是在这种氛围下产生的。在uClinux这个英文单词中u表示Micro,小的意思,C表示Control,控制的意思,所以uClinux就是Micro-Control-Linux,字面上的理解就是"针对微控制领域而设计的Linux系统"。想了解Linux命令可参考下图:

B. arm-linux-gcc 和 arm-elf-gcc 的区别

在基于ARM的嵌入式系统开发中,常常用到交叉编译的GCC工具链有两种:
arm-linux-*和 arm-elf-*,两者区别主要在于使用不同的C库文件。arm-linux-*使用
GNU的Glibc,而arm-elf-*一般使用 uClibc/uC-libc或者使用REDHAT专门为嵌入式系统
的开发的C库newlib.Glibc。uClibc/uC-libc以及 newlib都是C语言库文件,只是所应
用的领域不同而已,Glibc是针对PC开发的,uClibc/uC-libc是与Glibc API兼容的小型
化C语言库,实现了Glibc部分功能。

关于uClibc/uC-libc的说明,详见如下:

There are two libc libraries commonly used with uClinux. uC-libc and
uClibc. They are quite different despite their similar names. Here is a
quick overview of how they are different.

uC-libc is the original library for uClinux. It was based on sources
from the Linux-8086 C library which was part of the ELKs project with m68000
support added by Jeff Dionne and Kenneth Albanowski. It is a fairly complete
libc implementation, however, some of the API's are a little non-standard
and quite a few common libc routines are not present. Currently it has
stable support for m68000, ColdFire and ARM (Non-MMU) architectures. It was
primary design goal is to be small and light weight. It does try to conform
to any standards, although its API tries to be compatible with most libcs,
it is not always exactly the same.

The uClinux distribution provides an environment that can compile using
either uC-libc or uClibc depending on your needs. For m68000 and Coldfire
platforms it is generally better to chose uC-libc as it supports shared
libraries and is the most commonly used libc for these CPUs. uClibc also
works quite well with almost all platforms supported by the distribution.
Which libc you choose to use will be decided by your requirements

uClinux有两个经常使用的libc库:uC-libc和uClibc。虽然两者名字很相似,其实有差
别,下面就简单的介绍一下二者的不同之处。uC -libc是最早为uClinux开发的库,是
Jeff Dionne和Kenneth Albanowski为在EKLs项目中支持m68000在Linux-8086 C库源码
上移植的。uC-libc是一个完全的libc实现,但其中有一些api是非标准的,有些libc的
标准也没有实现。uC-libc稳定地支持 m68000,ColdFire和没有MMU的ARM。其主要设计
目标是“小”、"轻",并尽量与标准一致,虽然它的API和很多libc兼容,但是似乎并
不像它期望的那样和所有标准一致。

uClibc就是为了解决这个问题从uC-libc中发展出来的。它的所有API都是标准的(正确
的返回类型,参数等等),它弥补了uC-libc中没有实现的libc标准,现在已经被移植到
多种架构中。一般来讲,它尽量兼容glibc以便使应用程序用uClibc改写变的容易。
uClibc能够在标准的 VM linux和uClinux上面使用。为了应用程序的简洁,它甚至可以
在许多支持MMU的平台上被编译成共享库。Erik Anderson在uClibc背后做了很多的工
作。uClibc支持许多系列的处理器:m68000,Coldfire,ARM,MIPS,v850, x86,
i960,Sparc,SuperH,Alpha,PowerPC和Hitachi 8。不断增加的平台支持显示uClibc
能够很容易的适应新的架构。uClinux发行版提供了环境能够让你选择使用uC-libc或是
uClibc编译。对于m68000和Coldfire平台来说,选择uC-libc还是稍微好一点,因为它
支持共享库,而共享库是这些cpu经常使用的 libc.uClibc也几乎和所有的平台都能很
好的工作。选择哪种libc取决于你的需求。

newlib 是一个用于嵌入式系统的开放源代码的C语言程序库,由libc和libm两个库组
成,特点是轻量级,速度快,可移植到很多CPU结构上。newlib实现了许多复杂的功
能,包括字符串支持,浮点运算,内存分配(如malloc)和I/O流函数(printf,fprinf()
等等)。其中libc提供了c 语言库的实现,而libm提供了浮点运算支持。

在为ARM交叉编译gcc编译器时,对gcc指定不同的配置选项时,使用的C语言库就不同,
gcc编译器默认使用Glibc,也可以使用 uClibc/uC-libc(基本兼容Glibc API),当使用
--with-newlib时,gcc编译器不使用Glibc。当没有交叉编译Glibc时,可以使用
--with-newlib禁止连接Glibc而编译bootstrap gcc编译器。从gcc源目录下的
config/arm中的t-linux和t-arm-elf中可以看出,不同的--target也影响gcc连接C语言
库,t-linux(--target=arm-linux)默认使用Glibc,-arm-elf(--target=arm-elf)使用
- Dinhibit_libc禁止连接Glibc,这时我们就可以使用newlib等其他C语言库编译GCC工
具链。

虽然GCC工具链配置了不同的的C语言库,但由于这些C语言库都可以用来支持GCC,它们
对核心数据的处理上不存在较大出入。因而arm-linux-* 和 arm-elf-*区别主要表现在
C语言库的实现上,例如不同系统调用,不同的函数集实现,不同的ABI\启动代码以及
不同系统特性等微小的差别。

arm-linux-*和 arm-elf-*的使用没有一个绝对的标准,排除不同库实现的差异,gcc可
以编译任何系统。arm-linux-*和 arm-elf-*都可以用来编译裸机程序和操作系统,只
是在遵循下面的描述时系统程序显得更加协调:

arm-linux-*针对运行linux的ARM机器,其依赖于指定的C语言库Glibc,因为同样使用
Glibc的linux而使得arm-linux-*在运行linux的ARM机器上编译显得更加和谐。

arm-elf-*则是一个独立的编译体系,不依赖于指定的C语言库Glibc,可以使用newlib
等其他C语言库,不要求操作系统支持,当其使用为嵌入式系统而设计的一些轻巧的C语
言库时编译裸机程序(没有linux等大型操作系统的程序),如监控程序,bootloader等

能使得系统程序更加小巧快捷。

Linaro prebuilt toolchain does support both hard and soft floating
point. You can get it from https://launchpad.net/linaro-toolchain-binaries/+milestone/2012.08 try: ./arm-linux-gnueabihf-gcc -print-multi-lib

The default configure is --with-arch=armv7-a --with-tune=cortex-a9
--with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb

To use soft floating, you need options: -marm -march=armv4t -mfloat-abi=soft.

In your case, please try to change -march=armv5 to "-march=armv4t"

If you want to change to configure to cortex-a8 and armv5. You need
* Change cortex-a9 to cortex-a8 in
samples/linaro-arm-linux-gnueabihf/crosstool.config
* Change armv4t to armv5 in
contrib/linaro/patches/gcc/linaro-4.7-2012.08/multilib.patch,

Then follow the instructions to rebuild the toolchain
(contrib/linaro/doc/README.txt)

BTW: crosstool-ng-linaro does not support multilib for eglibc. It uses
the prebuilt sysroot from Ubuntu Precise. If it does not work for you,
please use the latest crosstool-ng from http://crosstool-ng.org/.

C. 如何配置uClinux2.6内核使其支持jffs2格式的文件系统

目前flash的文件系统比较多,用的比较多的就是JFFS2文件系统。基于NOR flash上的JFFS2文件系统可以说算是比较成熟了,支持NAND flash的JFFS2也已经发布了。源代码可以到http://www.linux-mtd.infradead.org上面下载。但是在我的测试过程中,在nand flash上挂接的JFFS2文件系统很不稳定,经常有CRC错误产生。特别是进行写操作的时候,每次复位都会产生CRC错误,可以说支持NAND flash的JFFS2文件系统目前还不成熟。而YAFFS文件系统则是专门针对NAND flash的,源代码可以到
http://www.aleph1.co.uk/yaffs/index.html上下载。在测试过程中稳定性能比JFFS2文件系统要稳定的多,而且mount分区的时间也比JFFS2文件系统少的多。用JFFS2 mount一个2m的文件系统大约需要1s。下面分别介绍在uclinux下面使用JFFS2和YAFFS文件系统。
1、JFFS2
到http://www.linux-mtd.infradead.org上面下载最新的MTD和JFFS2压缩包。压缩包里面还有有关的内核补丁和一些MTD的相关工具。主要的补丁就是ilookup- 2.4.23.patch,因为最新的MTD驱动中要用到一个ilookup()函数。打完补丁、更新了MTD驱动和JFFS2文件系统之后就开始写自己 nand flash驱动了。如果不想把JFFS2作为根文件系统的话,还需要修改MTD_BLOCK_MAJOR。驱动可以参考里面的例子,最简单的就是参考 spia.c。
写驱动主要工作是定义flash分区结构、定义flash读写地址、写控制flash的**_hwcontrol()函数。具体的操作要看所用的nand flash的芯片资料。相对NOR flash来说驱动要简单多了。:)
改完之后再配置
Memory Technology Devices(MTD)下
CONFIG_MTD=Y
CONFIG_MTD_DEBUG=Y
CONFIG_MTD_DEBUG_VERBOSE=3
CONFIG_MTD_PARTITIONS=Y
CONFIG_MTD_CHAR=Y
CONFIG_MTD_BLOCK=Y
NAND Flash Device Drivers下
CONFIG_MTD_NAND=Y
定义自己的驱动文件
File systems下
CONFIG_JFFS2_FS=Y
CONFIG_JFFS2_FS_DEBUG=2
CONFIG_JFFS2_FS_NAND=y /*这个是新加的*/
在uClinux v1.3.4 Configuration下
Flash Tools下
CONFIG_USER_MTDUTILS=Y
CONFIG_USER_MTDUTILS_ERASE=Y
CONFIG_USER_MTDUTILS_ERASEALL=Y
CONFIG_USER_MTDUTILS_MKFSJFFS2=Y
最后就是辛苦了调试工作了。:(MTD驱动调试完之后,就可以在上面挂接JFFS2文件系统了。参看flash分区情况:cat /proc/mtd,擦除分区:eraseall /dev/mtd*.例如把第一个分区mount到/mnt目录下面:
先:eraseall /dev/mtd0
然后:mount -t jffs2 /dev/mtdblock0 /mnt
2、YAFFS
YAFFS意义为'yet another flash file system',也是一个开源的文件系统。YAFFS是目前为止唯一一个专门为NAND flash设计的文件系统,具有很好的可移植性,能够在linux,uclinux,和wince
下面运行。
在http://www.aleph1.co.uk/yaffs/index.html上下载源代码。压缩包里面也包含YAFFS的说明文档。YAFFS文件系统的源文件就devextras.h,yaffs_ecc.c, yaffs_ecc.h,yaffs_guts.c,yaffs_guts.h,yaffs_mtdif.h,yaffs_mtdif.c和 yportenv.h
另外需要配置的宏:CONFIG_YAFFS_FS 和CONFIG_YAFFS_MTD_ENABLED,就是配置在mtd上面挂接YAFFS,其它还有一些辅助配置需要时也可以配置。
在fs目录下面建一个yaffs目录,把以上说的文件考里面去,新建一个makefile:
O_TARGET := yaffs.o
obj-y := yaffs_fs.o yaffs_guts.o yaffs_mtdif.o yaffs_ecc.o
obj-m := $(O_TARGET)
include $(TOPDIR)/Rules.make
接下来就是改fs目录下面config.in和makefile,在配置YAFFS的时候,把YAFFS连接进去。
如果像前面一样已经把NAND MTD驱动调好了,加YAFFS就很简单了。因为YAFFS是自己做ECC校验的,所以要把MTD驱动里面的ECC去掉。在驱动里面改成this->eccmode = NAND_ECC_NONE就可以了。
另外YAFFS是用mkyaffs来擦除flash,所以在mtd-utils中加上mkyaffs.c,一起编译进去。
最后就是编译了,呵呵。中间会有一些警告没有关系的,就是写没有用的变量和函数,不过话说回来YAFFS的代码写的确实不太规范。当然它的性能确实没话说。有兴趣的可以试一下。

D. uclinux内核编译问题

在Ubuntu 下输入 apt-get install ncurses
Redhat下输入 rpm -ivh ncurses
这个问题应该是在输入make menucongfig时候出现的,内核启动文本配置,需要
ncurses库

E. 如何使uClinux根目录使用jffs2分区

一、系统介绍
1. 采用加补丁方式的uClinux内核,不是uClinux-dist结构的。原始linux 2.4.22
2. Flash 地址0x46000000 ---- (0x46800000-0x1)
3. 192K 存放loader所以映像烧写起始 0x46030000
4. 832K 存放内核 0x46030000----(0x46100000-0x1)
5.
二、打开jffs2支持
File systems --->
<*> Journalling Flash File System (JFFS) support
(0) JFFS debugging verbosity (0 = quiet, 3 = noisy)
<*> JFFS stats available in /proc filesystem
<*> Journalling Flash File System v2 (JFFS2) support
(0) JFFS2 debugging verbosity (0 = quiet, 2 = noisy)

Memory Technology Devices (MTD) --->
<*> Memory Technology Device (MTD) support
<*> MTD partitioning support
<*> Direct char device access to MTD devices
<*> Caching block device access to MTD devices

RAM/ROM/Flash chip drivers --->
<*> Detect flash chips by Common Flash Interface (CFI) probe
<*> Support for AMD/Fujitsu flash chips
三、分区说明
文件:driver/mtd/maps/xxxxx_map.c 有(不同的厂商或flash会有不同的map文件)
static struct mtd_partition xxxxmap_partitions[] = {
XXXXX_MTD_PARTITIONS
} 结构对应分区
宏XXXXX_MTD_PARTITIONS对应在 (有一些是不用宏直接写在结构里也一样)
include/asm-arm/arch-xxxxx/board-xxxxx/mtdpartitions.h 文件中
测试时分了一个区8M的最后2M。分区如下
{ /* 2MB:test */ /
name: "test jffs2", / /*分区名称,启动时候会显示*/
size: 0x200000, / /*分区大小两兆*/
offset: 0x600000, / /*6M处开始*/
mask_flags: 0, / /*0表示读写*/
}
编译后在系统中会产生/dev/mtdblock/0 和 /dev/mtdblock/1;/dev/mtdblock/1就是对应该分区。
注:我用的版本会自动产生设备文件,它使用一个所谓的devfs,比我以前用过要在Makefile中添加设备节点的方便多了。
四、用最简单的方法进行测试
1. 格式化
在开发系统中新建jffs2目录随便放个文件
mkfs.jffs2 -d ./jffs2 -o jffs2.img –l –U (mkfs.jffs2 可在mtd包的util目录中编译生成)
编译好带网络的映像,写入,启动,映射好nfs。在uClinux中运行
cat ./jffs2.img > /dev/mtdblock/2 (格式化前一定要使用bootloader erase该分区)
2. 使用
mount -t jffs2 /dev/mtdblock/1 /mnt
进入/mnt 目录测试一下
五、根目录使用jffs2分区
1. 方案说明
内核映像还是放在romfs文件系统中,一般bootloader仅仅支持romfs的启动。Root文件系统制作成jffs2的映像。连接到romfs下面。最后进行整体烧入。
2. 8Mflash具体分区
{ /* 7104KB read/write */ / /*root 文件系统*/
name: "Root fs", /
size: 0x6f0000, /
offset:0x100000, /
mask_flags: 0, /
}, /
{ /* 64KB read/write */ / /*分1块其他用途*/
name: "User", /
size: 0x10000, /
offset: 0x7f0000, /
mask_flags: 0, /
}, /
#if 0 //可以分出来,但最好不要,没有用处,里面的内容也不是jffs2结构
//前面1M是laoder和内核
{ /* 192KB readonly: bootloader */ /
name: "BootROM", /
size: 0x20000, /
offset: 0x0, /
mask_flags: 0, /* Not writable */ /
}, /
{ /* 832KB: kernel*/ /
name: "Kernel", /
size: 0xe0000, /
offset: 0x20000, /
mask_flags: 0, /
}
#endif
这样/dev/mtdblock/1就是root分区了
3. 关于启动命令行do_mounts.c::__setup
General Setup --- >
[*] Compiled – in Kernel Boot Parameter
Default kernel command string : “root=/dev/mtdblock1 rw”

该配置产生的结果保存在include/linux/autoconf.h 中
注意 root=/dev/mtdblock1 rw,1的前面的 / 是没有的。在程序中do_mounts.c
static int __init root_dev_setup(char *line) 中把/dev/mtdblock1转化成 kdev_t ROOT_DEV; 来保存rootfs设备主从设备号。加了/后解析从设备号就出错,默认为 0 了,导致mount错误。
加了 rw ,__setup("rw", readwrite) 语句会调用static int __init readwrite(char *str) 函数,把root_mountflags 设置成可写。相关函数mount_block_root("/dev/root", root_mountflags) (在调用之前 "/dev/root" 被映射到mtd设备了)
4. 关于blkmem
Block devices --- >

< > Rom dis memory block device (blkmem)
[ ] Per partition statistics in /proc/partitions
blkmem去掉,否则在blkmem模块加载的时候会修改全局变量ROOT_DEV,到运行mount_block_root 使已经不是对应的mtd设备了。具体见blkmem.c : int __init blkmem_init( void ) 函数的最后几行。
5. 关于jffs
File systems--- >

< > Journalling Flash File System (JFFS) support

去掉 jffs的支持,我使用的时候不知道为什么 jffs 会mount jffs2格式成功,但最后肯定是不能用的。mount_block_root 函数中会循环系统中所有支持的文件系统去 mount root分区。找到mount成功就停止循环。去掉后就不会循环到 jffs系统了,先用ext2试了一下失败,就是用jffs2加载了。
6. 映像文件的制作
下面列举我的制作脚本(在 make romfs 后运行)
#制作一个romfs目录仅仅存放一个linux.bin.gz文件的内核文件系统
cd /home/hge/armutils_xxxxx
rm -rf ./build_arm/romfs
mkdir -p ./build_arm/romfs
cp “内核根目录下的linux.bin” ./build_arm/romfs/linux.bin
gzip -f ./build_arm/romfs/linux.bin

#romfs 制作内核文件系统映像并使文件固定为823K即flash存放内核的大小
genromfs -f ./bin/hge-romfs-linux.bin -V mambo -d ./build_arm/romfs
cat ./bin/hge-romfs-linux.bin /dev/zero | dd of=./bin/hge-romfs-fixsize.bin bs=1024 count=64 bs=1024 count=832

#在内核文件系统映像的前后各加上64K空白
#所以romfs其实是从第二个64K块开始,而jffs2则从对应分区的第三个块开始
#内核实际数据是不能大于823 – 64 = 768K,root分区很大少128K影响不大
#例子是这样,否则可能出现很多错误信息,但好像还是可以使用
dd if=/dev/zero of=./bin/64KB_blank bs=1024 count=64
cat ./bin/64KB_blank ./bin/hge-romfs-fixsize.bin ./bin/64KB_blank > ./bin/hge-romfs-rootfs.bin

#rootfs 制作jffs2 格式的root 文件系统
rm -rf ./build_arm/romfs
mkdir -p ./build_arm/romfs
cp -Rdf ./build_arm/root/* ./build_arm/romfs
/home/hge/mkfs.jffs2 -d ./build_arm/romfs/ -o ./bin/hge-rootfs-jffs.img -l -U

#romfs+rootfs 两个文件连接起来
cat ./bin/hge-rootfs-jffs.img >> ./bin/hge-romfs-rootfs.bin

#gzip
gzip -fc ./bin/hge-romfs-rootfs.bin > ./bin/hge-romfs-rootfs.bin.gz

#uuencode
uuencode ./bin/hge-romfs-rootfs.bin.gz x.gz > ./bin/hge-romfs-rootfs.bin.gz.uue

最后 hge-romfs-rootfs.bin.gz.uue 用来烧写
7. 烧写注意
必须把jffs2 文件系统对应的flash 全部擦除后再进行烧写,否则那些多余的数据也会被当作文件系统的数据导致CRC错误。
boot> flash erase 0x46030000 0x467d0000
8.
六、其他
在内核启动mount文件系统前会运行一个 linux-2.4.22-XX/init/main.c : init 函数,在函数中有prepare_namespace 函数就是整个文件系统的初始化了。

F. UC/OS与Linux操作系统的区别

uc/os比较简单一点,开始学的uc/os,感觉没意思了就开始学linux,感觉ucos只是在单片机上跑跑,像arm9的一般是跑linux。其实先学哪个都差不多,因为学习方法大不相同,差别太大了,ucos太简单,就一些信号量,邮箱什么的,懂了也就会了,linux有点难,涉及知识太多,光是涉及内核以外的编程就需要大把大把的经典书籍去看。兴趣很重要,都靠兴趣过来的。

阅读全文

与uclinux编译工具相关的资料

热点内容
java设置标题栏颜色设置 浏览:632
win10可用的ewf 浏览:100
怎么把知网caj文件格式改为pdf 浏览:209
b2c电商网站源码java 浏览:678
编程在什么电脑上都能学吗 浏览:941
java输出五行菱形 浏览:745
u盘文件删除不了提示权限 浏览:660
怎么把word的文件名字提取出来 浏览:215
小米怎么传文件到电脑 浏览:19
codm游玩会产生哪些文件 浏览:346
下编程软件什么网站好 浏览:34
js画一个表盘刻度 浏览:496
win10更新后分辨度灰色 浏览:888
怎样在qq日志里加音乐 浏览:827
什么可以控制脑电波编程语言 浏览:505
微信是否能建文件包 浏览:536
qq群闪图在文件夹哪里 浏览:753
js跳出each循环语句 浏览:145
c把结果输出到文件格式 浏览:596
怎么样将cad文件发到微信上 浏览:835

友情链接