备忘一次嵌入式实训之一 定制linux内核
一说明
此文档所有操作建立在嵌入式开发环境已经具备的情况下,所有步骤都经过测试且已通过,以下为软硬件环境的具体参数.
操作系统: 非虚拟机下 Fedora17 (x64)
>uname -a
>[输出]
Linux lvzaina.lc 3.6.10-2.fc17.x86_64 #1 SMP Tue Dec 11 18:07:34 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
#理论上操作系统内核版本基本不会对将要进行的linux系统移植/驱动移植以及开发产生影响,但是请特别注意:编译时调用的库文件不相同可能会产生未知的后果.
移植系统版本:
linux-2.6.36
编译环境:
arm-linux-gcc:
#PS:编译过程中提示库文件不能被发现之类的错误皆为编译环境搭建的问题,请自行谷歌解决.类似错误: error while loading shared libraries: libmpfr.so.1: cannot open shared object file: No such file or directory
二 移植linux操作系统(根文件系统)到实验平台
1.解压内核源代码
切换到源文件存放路径
执行 ' tar -jxvf linux-2.6.36.tar.bz2 -C /xxx/ '
解压到目标目录
2. 指定体系架构
进入解压后的内核源码文件夹下,编辑Makefile文件修改编译参数
#修改默认体系架构
>找到191行: ' ARCH ?= $(SUBARCH) '
>修改为 : ' ARCH ?= arm '
#指定交叉编译器
>找到192行: ' CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) '
>修改为 : ' CROSS_COMPILE ?= arm-linux- '
#保存
3. 定制编译配置文件
linux-2.6.36 的配置文件列表可通过命令(需在源码根目录下执行) :
make help
查看,在显示的众多配置文件名中我们可以找到
s
3c6400_defconfig - Build for s3c6400
由于实验板基于s3c6410芯片,故我们使用最相近的 s3c6400_defconfig 配置文件,使用命令
[root@lvzaina linux-2.6.36]# cp arch/arm/configs/s3c6400_defconfig .config
拷贝该配置文件到根目录下,作为内核编译默认配置文件
此步骤后我们变可以通过' make menuconfig '命令进入内核编译选项配置图形化界面.
4. 选择内核编译选项
System Type --->
( 2 )S3C UART to use for low-level messages
//选择串口通信调试端口
取消
Power management options --->
[]Power Management support
//经测试为非必要
添加
Networking support --->
Networking options --->
[*] TCP/IP networking
//网络文件系统,此处添加网络TCP/IP协议支持
添加
Device Drivers --->
Network device support --->
Ethernet (10 or 100Mbit) --->
<*> SMSC LAN911x/LAN921x families embedded ethernet support
//网卡驱动支持
添加
General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
选择下方的()Initramfs source file(s) 回车
填写你制作的跟文件系统的目录
PS:还有部分选项已经为 s3c6400_defconfig 配置文件中默认配置,无需手工配置,下面会有部分介绍,但具体各个选项的作用,建议谷歌之,当了解之后可以可尝试自己配置出自己想要的内核.
PS:如果发生
Uncompressing Linux...done, booting the kernel 停止
解决办法:
添加system 支持--->>smdk6410
还有可能是uboot bootargs参数设置错误
至此,内核配置大体完成,可能你会发现,上面的选项支持了三种方式来启动文件系统,分别是
-
<ramdisk虚拟根文件系统启动Linux>
-
<initramfs虚拟根文件系统启动Lin ux>
-
<网络根文件系统启动Linux>
下面将介绍这三种方式,及其配置
从ramdisk根文件系统启动Linux,这种方式需要分别制作内核镜像和ramdisk根文件系统镜像,然后通过uboot将两镜像烧写到板子上的存储介质中(flash),再通过修改uboot引导内核启动的参数bootargs和bootcmd来启动linux.所谓的ramdisk技术是在内存中模拟出一个磁盘,其结构为你制作的根文件系统的结构,所以必须添加Device Drivers-->Block devices-->RAM block device support 即ramdisk驱动支持,并且必须在其后的' ()Default RAM disk size kbytes '选项里填写正确的ramdisk镜像尺寸大小.而通常情况下ramdisk是采用Ext2文件系统的,故而选择ext2文件系统支持选项File systems --> <*> Second extended fs support也是必须的(当然你也可以尝试使用其他文件系统制作你的虚拟根文件系统镜像,但要记得添加支持选项).
Initramfs根文件系统启动Linux,这种方式相较第一种更加灵活更加干净漂亮,下面这段介绍取自网络,可以很好的理解两种方式:
ramdisk是一个基于ram的块设备,因此它占据了一块固定的内存,而且事先要使用特定的工具比如mke2fs格式化,还需要一个文件系统驱动来读写其上的文件。
如果这个disk上的空间没有用完,这些未用的内存就浪费掉了,并且这个disk的空间固定导致容量有限,要想装入更多的文件就需要重新格式化。
由于Linux的块设备缓冲特性,
ram disk上的数据被拷贝到page
cache(对于文件数据)和dentry
cache(对于目录项),
这个也导致内存浪费.
initramfs:
最初的想法是Linus提出的:
把cache当作文件系统装载.
他在一个叫ramfs的cache实现上加了一层很薄的封装,
其它内核开发人员编写了一个改进版tmpfs,
这个文件系统上的数据可以写出到交换分区,
而且可以设定一个tmpfs装载点的最大尺寸以免耗尽内存.
initramfs就是
tmpfs的一个应用.
优点:
(1)tmpfs随着其中数据的增减自动增减容量.
(2)在tmpfs和page
cache/dentry cache之间没有重复数据.
(3)tmpfs重复利用了Linux
caching的代码, 因此几乎没有增加内核
尺寸,
而caching的代码已经经过良好测试,
所以tmpfs的代码质量
也有保证.
(4)不需要额外的文件系统驱动.
另外,
initrd机制被设计为旧的"root="机制的前端,
而非其替代物,
它假设真正的根设备是一个块设备,
而且也假设了自己不是真正的根设备,
这样不便将NFS等作为根文件系统,
最后/linuxrc不是以PID=1执行的,
因为
1这个进程ID是给/sbin/init保留的.
initrd机制找到真正的根设备后将
其设备号写入/proc/sys/kernel/real-root-dev,
然后控制转移到内核由其装载根文件系统并启动/sbin/init.initramfs则去掉了上述假设,
而且/init以PID=1执行,
由init装载根文件
系统并用exec转到真正的/sbin/init,
这样也导致一个更为干净漂亮的设计
你如果想了解更多,可以通过以下两个网页:
[1] 黃敬群先生的blog:深入理解 Linux 2.6 的 initramfs 機制
[2] initramfs, a new model for initial RAM
http://blog.linux.org.tw/~jserv/archives/001954.html
通过上述文字,可以知道initramfs技术不需要像ramdisk那样通过文件系统驱动来读写其上的文件,故而File systems --> < > Second extended fs support项以及Device Drivers-->Block devices-->RAM block device support 项就可以取消了,而General setup --->[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support必须选中而且填写正确的根文件系统目录.
网络根文件系统启动Linux,顾名思义,就是根文件系统搭建在与设备相连的网络中,与上面两种的差异在于设备必须有良好的网络支持,包括 TCP/IP协议支持 网卡驱动支持 NFS支持,上面选项File systems --->[*] Network File Systems --->[*] Root file system on NFS 便是网络根文件系统的支持项,一般来讲即便不使用网络根文件系统,也应该添加网络支持来方便我们调试内核以及驱动程序。
这篇文档将主要说明 如何从initramfs根文件系统启动Linux。
----------------------------------------------------------------------------------------------------------------
本文引用通告地址:http://www.cnblogs.com/lvzaina/
----------------------------------------------------------------------------------------------------------------