Linux内核
文件
在内核下输入:du --max-depth=1 –h
可以发现内核源码主要是drivers和arch
Makefile
顶层Makefile:
对应平台可以通过变量 ARCH 来指定:
ARCH = arm
对应交叉编译器可以通过变量 CROSS_COMPILE 来指定:
CROSS_COMPILE = arm-linux-gnueabihf-
子目录的Makefile:
管理着对应的目录下的代码。Makefile中有两种表达方式,一种是默认选择编译,用obj-y表示,如:
obj-y +=usb-host.o #默认编译usb-host.c文件
obj-y +=gpio/ #默认编译gpio目录
这类一定会编译进内核
另一种表示则与内核配置选项相关联,编译与否以及编译方式取决于内核配置,例如:
obj-$(CONFIG_WDT) +=wdt.o #wdt.c编译控制
obj-$(CONFIG_PCI) +=pci/ #pci目录编译控制
这类是否编译,取决于内核配置是否选中:如果在配置中设置为[*],则静态编译到内核,如果配置为[M],则编译为 wdt.ko 模块,否则不编译
Kconfig
用于描述所在目录源代码相关的内核配置菜单,make menuconfig的时候从Kconfig文件读取菜单,配置完毕保存到文件名为.config的内核配置文件中,供Makefile在编译内核时使用
结合以上:
Makefile决定内核编译时模块: 编译/不编译/编译成模块
Kconfig决定内核配置时模块:可选的操作方式
.config
内核编译的配置文件,在<arch/arm/configs/>目录下有很多*_defconfig 文件,这些都是内核的预设配置文件,分别对应各种不同的参考板。
内核配置菜单
Linux中I/O设备分为两类:块设备和字符设备。两种设备本身没有严格限制,但是,基于不同的功能进行了分类。
(1) 字符设备:提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。相反,此类设备支持按字节/字符来读写数据。举例来说,调制解调器是典型的字符设备。
(2) 块设备:应用程序可以随机访问设备数据,程序可自行确定读取数据的位置。硬盘是典型的块设备,应用程序可以寻址磁盘上的任何位置,并由此读取数据。此外,数据的读写只能以块(通常是512B)的倍数进行。与字符设备不同,块设备并不支持基于字符的寻址。
两种设备本身并没用严格的区分,主要是字符设备和块设备驱动程序提供的访问接口(file I/O API)是不一样的。本文主要就数据接口、访问接口和设备注册方法对两种设备进行比较
想要了解自己网上查看!!
编译内核
编译内核:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j8 uImage
"-jN":N的值为处理器核心数量的2倍
uImage和zImage:
对于ARM Linux 系统,大多数采用 U-Boot 引导,很少直接使用 zImage 映像,实际上更多的是 uImage。uImage 是 U-Boot 默认采用的内核映像文件,它是在 zImage 内核映像之前加上了一个长度为 64 字节信息头的映像。这 64 字节信息头包括映像文件的类型、加载位置、生成时间、大小等信息
加载内核:
# tftp 40007fc0 uImage
# bootm 40007fc0
编译内核模块:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- modules
指定编译内核模块的路径:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- INSTALL_MOD_PATH=/home/chenxibing/work/rootfs modules_install
加载内核模块:
imsmod:一个个加载,需要考虑ko的依赖关系和路径
modprobe:直接加载,无需考虑ko的依赖关系和路径