Linux内核移植

1.内核体系结构

  • 站在较高的角度看 Linux操作系统的体系结构,可以从两个层次上来考虑操作系统,如图所示。最上面是用户(或应用程序)空间。这是用户应用程序执行的地方。用户空间之下是内核空间,Linx内核正是位于这里。

Linux内核移植_第1张图片

  • 内核和用户空间的应用程序使用不同的保护地址空间。每个用户空间的进程都使用自己的虚拟地址空间,内核则占用单独的地址空间,一般情况下,应用程序无法直接访问内核空间地址。因此,应用程序想访问内核必须通过某种特殊的方式从用户空间切换到内核空间。这个特殊的方式称为系统调用。
  • 考虑到频繁的系统调用会影响操作系统的性能(切换开销、硬件损耗等),标准C库GNLibrary glibe)提供了新的连接内核的接口,这些接口同样通过系统调用访问内核,不过通常都带有缓冲区,将数次操作合并为一次,以有效减少系统调用的次数。
  •  Linux内核可以进一步划分成3层。最上面是系统调用接口,它实现了一些基本的功能,如read和 write。系统调用接口之下是与体系结构无关的内核,这部分内核对于Linux支持的所有处理器体系结构是通用的。其下是体系架构相关的部分,通常称为BSP( Board Support Package)。这部分内核与特定体系架构的处理器和特定的平台相关

2.内核组件

  • 如图所示,Linux内核主要由系统调用接口(SCI)进程管理(PM)内存管理(MM)虚拟文件系统(VFS)网络协议栈(NET)CPU体系结构(Arch)设备驱动(DD)等7个组件构成。

Linux内核移植_第2张图片

(1)系统调用接口

  • SCI层提供了某些机制执行从用户空间到内核的函数调用。这些接口依赖于体系结构,在内核 kerel目录中,可以找到SCI的实现,并在内核arch目录中能找到依赖于体系结构的部分。

(2)进程管理

  • 进程管理的重点是进程的执行。在内核中,这些进程称为线程,代表了单独的处理器虚拟化(线程代码、数据、堆栈和CPU寄存器)。在用户空间,通常使用进程这个术语,不过 Linux实现并没有区分这两个概念(进程和线程)。内核通过SCI提供了一个应用程序编程接口来创建一个新进程(fork、exec或 POSIX(Portable Operating System Interface)函数)和停止进程(kill、exit)并在它们之间进行通信和同步(信号或者 POSIX机制)

(3)内存管理

  • 内核管理的另外一个重要资源是内存。为了提高效率,内存按照内存页的方式进行管理,页大小通常是4KB。Linux内存管理主要负责内存的分配和释放,以及物理地址到虚拟地址的映射等

(4)虚拟文件系统

  • 虚拟文件系统(VFS)是 Linux内核中非常有用的一个组件,因为它为文件系统提供了个通用的接口抽象。VFS在SCI和内核支持的文件系统之间提供了一个交换层,如图所示。

Linux内核移植_第3张图片

  • 在VFS上面,是对诸如open、close、read和writ之类的系统调用函数的一个通用抽象。在VFS下面是对文件系统的抽象,它定义了上层函数的实现方式。文件系统的源代码可以在内核fs目录中找到。
  • 文件系统层之下是缓冲区缓存,它为文件系统层提供了一个通用函数集(与具体文件系统无关)。这个缓存层通过将数据保留一段时间,优化对物理设备的访问。缓冲区缓存之下是设备驱动程序,它实现了特定物理设备的接口。

(5)网络协议

  • 网络协议栈在设计上采用分层思想,从上到下分为系统调用接口层协议无关接口层网络协议层设备无关接口层设备驱动程序层。
  • 其中协议无关层也就是socket层,提供了一组通用函数来支持各种不同协议。 socket层不但可以支持典型的TCP和UD协议,而且可以支持IP、裸以太网和其他传输协议,如SCTP( Stream Control Transmission Protocol)。内核中的网络源代码可以在net目录中找到。

3.内核目录结构

  • Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个目录下,使得程序更具有可读性。以2.629的代码为例,在内核顶层目录下可以看到很多子目录,下面列出了其中比较重要的几个。下载内核源代码地址www.kernel.org

Linux内核移植_第4张图片

4.Linux内核的配置与编译

(1)配置内核

1.交叉编译设置

  • 在默认情况下,内核构建系统默认内核是本地编译的,即编译的内核运行在与宿主系统相同的体系架构上。如果是为其他的架构编译内核,即交叉编译,需要设置两个变量:ARCH和 CROSS_COMPILE。其中:ARCH指明目标体系架构,即编译好的内核运行在什么平台上,如x86、arm或mips等。CROSS_COMPILE指定使用的交叉编译器的前缀。交叉工具链的前缀是:arm-linux-。
  • 可以在每次执行make时,通过命名行为这两个变量的赋值:make ARCH=arm CROSS_COMPILE=arm-linux-
  • 也可以直接修改顶层Makefile,这样比较方便。

Linux内核移植_第5张图片

2.加载默认配置

  • 内核有成千上万的配置项,因此,通常不会完全从零开始配置内核。在arch/arch> configs目录下(对应具体的架构,如x86、amm和ppc等),内核提供了各种平台的默认配置文件。例如,对于arm架构,内核为三星的S3C24X0平台提供了默认配置文件 s3c2410 defconfig。
  • 加载三星的S3C24X0平台的默认配置,可以使用如下命令:make ARCH=arm s3c2410_defeonfig,这个操作效果等同于将arc、arch/arm/configs目录下的s3c2410_defconfig文件复制为.config。
  • 通常默认的配置并不能完全满足实际需求但有了一个与所用开发板比较接近的默认配置,在此基础上调整起来将会更加容易加载默认配置后,可以使用make menuconfig对内核配置进行调整。

Linux内核移植_第6张图片

3.基本配置选项

(1)General setup

  • 通用设置选项菜单包括“System V IPC ”、“POSIX Message Queues”等特定进程通信方式的内核配置,以及类似“Local version-append to kernel release”、“Optimize for size”的通用设置项。

 (2)Enable loadable module suppor

  • 选中该选项表示允许内核动态加载模块。执行make menuconfig后可以使用空格键选中该选项。回车进入该选项的子菜单,选中“Module unloading可以允许内核动态卸载模块,如图所示。

Linux内核移植_第7张图片

 (3)System Type

  • 系统类型选项菜单,在其中配置处理器相关的选项。例如,对于ARM架构,其中的选项“ARM system type用于选择具体的ARM处理器平台类型

(4)Kernel Features

  • 内核特性选项菜单,进入“Kemel Features菜单,可以看到如图所示的子选项。

Linux内核移植_第8张图片

  • 其中选项“Memory split”用于配置用户空间和内核空间的大小,选项Preemption Model (No Forced Preemption (Server))  子选项“Preemptible Kemel”用于使能抢占式内核,选项“Use the ARM EABI to  compile the kemel”则决定内核是否按照EABI接口编译内核。

 (5)Bootoptions

  • 启动选项菜单,其中包括配置默认启动参数的选项。

(6)Userspace binary formats

  • 用户空间二进制文件格式选项菜单,其中包括使内核支持LF格式文件的选项“Kemel support for ELF binaries

(7)Networking support

  • 网络协议栈选项菜单

(8)Device Drivers

  • 设备驱动选项菜单,按照char、MID、ATA、SCSI、2、sp、usb、 MMC/SD sound、IEE1394、IDA等设备设立了多个子菜单。

(9)File systems

  • 文件系统选项菜单,包含对Ex2,Ext3、FAT、NFS等多种文件系统的配置选项。

( 10)Kemel hacking

  • 内核开发选项菜单,包括内核各组件的调试开关选项,如文件系统调试开关“Debug Filesystem” Debug slab memory allocations等,也包括内核底层调试功能开关“Kemel low-level dehugging functions”,开启底层调试功能可以让内核在启动之初通过串口打印调试信息。

4.编译内核

(1)清除原有配置与中间文件

  • x86: make distclean
  • arm: make distclean

(2)配置内核

  • 首先根据默认配置文件进行配置(.config文件
  • x86: make menuconfig
  • arm: make menuconfig ARCH=arm(默认x86平台

(3)编译内核

  • x86: make bzImage
  • arm: make uImage ARCH=arm CROSS_COMPILE=arm-linux-(如果在顶层Makefile已修改环境变量,则直接make uImage)

Linux内核启动分析

  • a.自解压内核 decompress(arch/arm/boot/ compressed/head.S)
  • b.运行内核汇编部分head.S入口 stext(arch/arm/ kernel/head.S)    
    • 检测合法性(CPU类型、机器类型)
  • c.运行内核C部分start_kernel(init/main.c)
    • CPU,机器参数的安装 setup arch
    • 中断,定时,终端,内存等最基本的初始化
    • 创建核心进程kernel_init运行,启动多任务调度
  • d.挂载rootfs
  • e.运行第一个应用程序init(一般是linuxrc)

你可能感兴趣的:(Linux底层驱动)