二、Linux驱动学习-内核

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的依赖关系和路径 

原文地址:https://www.cnblogs.com/Just-a-calm-programmer/p/13441390.html