一、linux体系结构
linux由内核空间与用户空间两部分组成,用户空间主要是应用程序和C库,内核空间包含了像系统调用接口,体系结构相关的代码。
现在的CPU实现了不同的工作模式,以ARM为例,实现了其中工作模式:
用户模式(usr)、快速中断(fiq)、外部中断(irq)、管理模式(SVC)、数据访问终止(abt)、系统模式(sys)、未定义指令异常(und)。
X86也实现了四个不同的级别:Ring0-Ring3 。 Ring0下,可以执行特权指令,可以访问IO设备等,在Ring3则有很多限制。Linux系统利用了CPU的这一特性,使用了其中的两级来分别运行linux内核与应用程序,这样使操作系统本身得到了充分保护。例如:如果使用X86,用户代码运行在Ring3,内核代码运行在Ring0.
内核空间与用户空间是程序执行的两种不同的状态,通过系统调用和硬件中断能够完成从用户空间到内核空间的转移。
linux 内核架构(这里用表模拟下)
System Call Interface | ||
---|---|---|
Porcess Management(PM) | Virtual Files System(VFS) | |
Memory Managemet(MM) | Network stack | |
ARCH | Device Drivers(DD) |
二、linux内核源代码
2.1 源代码下载
www.kernel.org 官网进行下载即可
2.2 目录结构(树形结构)
arch目录:architecture的缩写。内核所支持的每种CPU体系,在该目录下都有对应的子目录。每个CPU的子目录,又进一步分解为boot,mm,kernel等目录,分别包含控制系统引导,内存管理,系统调用等。
document目录:内核的文档部分
drivers目录:设备的驱动程序目录
include目录:内核所需要的头文件。与平台无关的头文件在 include/linux 子目录下,与平台相关的头文件在相应的子目录中。
fs目录:存放各种文件系统的实现代码。每个子目录对应一种文件系统的实现,公用的源程序用于实现虚拟文件系统VFS:
||–devpts /dev/pts 虚拟文件系统
||–ext2 第二扩展文件系统
||–fat MS的fat32文件系统
||–isofs ISO9660光盘CD-ROM上的文件系统
net目录:网络协议的实现代码:
||–802 802无线通讯协议核心支持代码
||–appletalk 与苹果设备互联协议
||–ax25 AX25无线Internet协议
||–bridge 桥接设备
||–ipv4 IP协议簇V4版32位寻址模式
||–ipv6 IP协议簇V6版128位寻址模式
三、linux内核配置与编译
配置内核:硬件需求,软件需求。
make config 这种方法是采用文本模式的配置
make menuconfig 这种是基于文本模式的菜单形配置
首选是采用菜单形配置(直观、简单、高效)
使用make menuconfig 配置内核
Process type and features
-----Process family
Networking support
-----Networking Options
Devices Drivers
-----Network device support
File system
这里说明下“[ ]”这种只有两种选择方式,有或者没有。而“ < > ”这种有三种选择方式。
<M> 内核模块,编译成.ko 动态调用。 “[]”直接便一道zImage内核映像中。
源代码的根目录中.config文件保存了内核配置结果,在源代码目录中使用 # ls -a 进行查看。
配置捷径:①:使用已有的配置项来改。 ②:不清楚的为默认值。
操作步骤如下:使用内核配置文件简化配置,当前linux系统的配置文件在 /boot/config-xxxx,如果是使用红帽6, 2.6.39内核可以直接使用其进行配置,将该 /boot/config-xxxx 文件复制到内核源代码。并输入以下命令
make menuconfig -> load an Alternate configuration File
填写刚刚复制的文件名字进入,保存后利用已经有的配置文件进行修改。
配置内核实际上工作很多,但是如果有厂商之前给你做好了相关配置文件,比如我这里购买的smart210,友善之臂提供了相关的配置文件名字叫 mini210_linux_defconfig(mini210和smart210基本一样)这个文件,这个就是厂商配置文件,这里我的在内核的根目录下面,使用下面命令就可以直接使用该配置文件进行编译:
cp mini210_linux_defconfig .config
make uImage ARCH=arm CROSS_COMPILE=arm-linux-
这样即可编译成功,同样还有一种方法简化内核配置,在 内核arch/arm/configs 中找到自己板子的默认配置,基于这个配置进行修改也是很好的,使用起来也很简单.
make xxx_defconfig
make menu_config ARCH=arm
make uImage ARCH=arm CROSS_COMPILE=arm-linux-
3.1 编译内核
<*> -> zImage
[M] -> 内核模块
make zImage 在X86平台上,zImage内核只能用于512KB的文件大小。
//所以一般都用下面的
make bzImage
如果需要获取详细的编译信息,可使用
make zImage V=1
make bzImage V=1
编译好的内核在: arch/<cpu>/boot
3.2 编译内核模块
make modules (大概一个小时时间,比较长)
make modules_install
编译过后生成的文件遍布于各个目录中,凡是以 *.ko 结尾的都是内核模块
make modules_install (将 *.ko 全部移动到/lib/modules)
这里是linux主机的/lib/不是源码的目录。
3.3 制作ramdisk
方法:mkinitrd initrd-$version $version
例:
mkinitrd initrd-2.6.39 2.6.39
// *$version 可以通过查询 /lib/modules 下目录得到。
3.4 安装内核(x86)
cp arch/x86/boot/bzImage /boot/vmlinuz-$version
cp initrd-$version /boot/
修改 /etc/grub.conf
3.5 清理文件
make clean :清理 *.0 *.ko 等文件
make distclean :在上面的基础上
四、嵌入式linux内核制作
4.1 清除相关文件
make distclean
4.2 配置内核
make menuconfig (x86)
make menuconfig ARCH=arm (ARM)
4.3 编译内核
make bzImage (X86)
make uImage ARCH=arm CROSS_COMPILE=arm-linux-
可能以上编译或许过不去,可能是因为源码中有配置initramfs这个挂载根文件系统的,所以过不去,因为这里还没有设置根文件系统,同时可能还有一个问题就是还缺少mkimage这个工具,需要从已经编译好的u-boot源码中tools中拷贝使用:
cp mkimage /bin/ 这里注意是拷贝到宿主机中