Linux内核

内核是所有Linux系统的中心软件组件。嵌入式领域所说的Linux,一般是指linux内核。移植也是指的移植linux内核到目标平台。

linux内核的版本号说明:
例,2.6.24
其中,2是主版本号,6是次版本号,24是修订版本号。
如果次版本号是偶数,说明是稳定版本。
如果次版本号是奇数,则是开发版本。

Linux内核源码目录结构

  • arch
    包含和硬件体系结构相关的代码,每种平台占一个相应的目录。如arm、avr32、blackfin、mips等。arch目录在系统移植过程中是需要重点修改的部分。
  • block
    块设备驱动程序的IO调度。
  • crypto
    常用的加密和离散算法,还有一些压缩和CRC校验算法。
  • drivers
    drivers目录中是系统中所有的设备驱动程序。它又进一步划分成几类设备驱动,如block、char、mtd、net、usb、video等待,每一种有对应的子目录,如声卡的驱动对应于drivers/sound。该目录占用了整个内核发行版本代码的一半以上,其中有些驱动程序是与硬件平台相关的,有些是与硬件平台无关,例如字符设备、块设备、串口、USB以及LCD显示驱动等。
  • Documentation
    内核说明文档。
  • fs
    该目录下列出了linux支持的所有文件系统。
    目前Linux已经支持包括JFFS2、YAFFS、ext3和NFS在内的多种文件系统,
    其中JFFS2常用于嵌入式系统NOR Flash中的文件系统,
    YAFFS常用于NAND Flash中的文件系统,
    ext3常用于台式PC机的Linux操作系统中的文件系统。
    还有一些伪文件系统,例如proc文件系统,可以以伪文件的形式提供其他信息
    (例如,在proc的情况下是提供内核的内部变量和数据结构)。虽然在底层并没有实际的存储设备与这些文件系统相对应,但是进程可以像有实际存储设备一样处理。
  • include
    头文件。与系统相关的头文件放在include/linux下,与arm体系结构相关的头文件放在include/asm-arm下。
  • init
    内核初始化代码。init目录包含核心的初始化代码(不是系统的引导代码),有main.c和version.c两个文件。这是研究核心如何工作的好起点。
  • ipc
    进程间通信代码。
  • kernel
    内核的核心代码,包括进程调度、定时器等。和arm平台相关的核心代码在arch/arm/kernel目录下。
  • lib
    lib目录包含了核心的库代码,不过与处理器结构相关的库代码被放在arch/lib目录下。Lib/inflate.c中的函数能够在系统启动时展开经过压缩的内核。Lib目录下剩余的其他文件实现一个标准C库的有用子集,主要集中在字符串和内存操作的函数(strlen、memcpy和其他类似的函数)及有关sprintf和atoi的系列函数上。
  • mm
    内存管理代码,和arm平台相关的内存管理代码在arch/arm/mm目录下。
  • net
    网络相关的代码,实现了各种常见的网络协议。例如TCP/IP、IPX等。
  • scripts
    scripts目录下没有代码,包含用于配置核心的脚本文件。当运行make menuconfig或make xconfig之类的命令配置内核时,用户就是和位于这个目录下的脚本进行交互的。
  • sound
    音频设备驱动的通用代码和硬件驱动代码都在这个文件下面。

Linux内核启动方案

Linux内核有两种映像:

  • 非压缩内核Image
  • 压缩内核zImage

嵌入式系统存储容量有限,因此通常选择压缩内核zImage。要使用压缩内核zImage,需要在映像开头加入解压缩代码,将zImage解压后,才可以执行。

内核编译完成后,会在arch/arm/boot目录下生成zImage文件。

zImgae文件的组成:

  • pggy.o : 压缩后的内核文件
  • head.o : 系统初级初始化代码文件
  • misc.o : 解压缩代码文件

Linux内核的配置

  • .config文件
    这是linux编译时所依赖的文件。我们在配置内核时所做的任何修改,最终都会在这个文件中体现出来。它是Makefile对内核进行处理的重要依据。
    一般来说,内核提供了芯片公司demo板的.config文件,我们一般找一个近似的进行修改。如S3C2410平台上可以选择s3c2410_deconfig这个文件。

三种配置方式

  • make config
    基于文本对话的配置方式,比较细致,但是浪费时间。对专业的内核开发人员比较合适。
  • make xconfig
    基于图形界面的配置方式。非常直观,但是需要特殊的软件支持,一般不推荐。
  • make menuconfig
    推荐的内核配置方式,采用目录的方式,直观,容易使用。

关于Kconfig
在进行make menuconfig时,目录的生成依赖于Kconfig文件。一般来说,每个源代码目录下都有一个Kconfig文件。

1
2
3
4
5
6
7
8
9
config DM9000
tristate "DM9000 support"
depends on ARM||BLACKFIN||MIPS
select CRC32
select MII
--help--
Support for DM9000 chipset
To compile this driver as a module, choose M here.
The module will be called dm9000.

Kconfig对.config文件的影响:

1
CONFIG_DM9000=y

make menuconfig对内核配置所做出的修改最终反应在.config文件中。如上所示,在.config文件中CONFIG_DM9000=y被定义为y。
CONFIG_DM9000是tristate类型,有三个可能取值:
y:编译进内核
m:编译成模块
n:不进行编译
若是bool类型,则只有两种可能,y或者n。

Kconfig对Makefile的影响:

1
obj-$(CONFIG_DM9000) += dm9000.o

关于Makefile
linux内核源码的每个目录下都有一个Makefile,由该Makefile对源代码的编译、链接等操作进行控制。

编译完成后,每个源代码目录下都会生成一个名叫built-in.o的文件。
这个文件由源代码目录下的所有源文件编译后的目标文件链接而成;
而不同的built-in.o又被上层目录中的Makefile链接成更大的builtin.o,直到最后链接成为一个内核vmlinux.o

内核镜像的制作

1
mkimage -A arm -T kernel -C none -O linux -a 0x30008000 -e 0x30008040 -d zImage -n 'linux-2.6.24' uImage
参数 解释
-A arm 目标平台是ARM架构的
-T kernel 要处理的是内核
-C none 不采用任何压缩方式
-O linux 要处理的Linux内核
-a 0x30008000 加载地址,包括mkimage工具给内核添加的头信息
-e 0x30008040 真正的内核入口地址,除掉mkimage添加的0x40长度的头信息
-d zImage 使用的源文件是编译Linux内核得到的zImage
-n ‘linux-2.6.24’ 生成的内核镜像的名字
uImage 生成的供U-Boot启动的二进制内核镜像

用U-Boot启动Linux内核

1.下载u-boot.bin到SDRAM的0x30008000处
tftp 0x30008000 uImage
2.启动内核
bootm 0x30008000

文章内容整理自:
www.cie-eec.org 相关文档