文章目录
Linux内核代码结构
- init
- kernel(内核管理核心代码)
- mm(memory management内核管理代码,处理器体系结构相关的代码仿真arch/*/mm)
- ipc(IPC进程间通信)
- lib(内核的库代码,体系结构相关的代码放在arch/*/lib)
- fs(file system文件系统)
- net(网络协议代码)
- drivers(系统中驱动程序代码)
- char(字符设备)
- usb(USB设备)
- block(块设备)
- pci(PCI总线)
- i2c
- spi
- include(Linux头文件)
asm-<arch>
(体系结构相关头文件)- linux(Linux kernel core 头文件)
- scripts(编译配置脚本文件)
- sound(声卡驱动程序)
- Makefile(顶层Makefile文件)
以上平台无关-------------------------以下平台相关
- arch(CPU架构相关代码,每个目录一个体系结构)
- i386
- arm
- kernel
- mm
- lib(体系结构相关的库代码)
- x86
- ppc
- m68k
- sh
模块化编程
module_init
和module_exit
宏将函数放在内核的某一段
module_init(initFunc);//模块的入口:完成模块的加载
module_exit(exitFunc);//模块的出口:完成模块的卸载
编译加载查看命令
- make 编译 生成
.ko
模块文件 - lsmod 显示模块
- insmod/rmmod 安装/卸载模块
- dmesg 打印log信息
linux内核源码默认装在/lib/modules/$(shell uname -r)/build
目录下
把一个模块独立于内核在外面编译再动态加载进去
make ... modules
符号导出
符号:全局变量和函数
Linux内核采用的是以模块化形式管理内核代码。内核中的每个模块相互之间是相互独立的,也就是说A模块的全局变量和函数,B模块是无法直接访问的。如果想要访问别的模块的变量或函数,就需要用到全局符号表。
Linux内核会把符号放在一个表里面,在编译的时候回去表里面找对应的全局变量和函数的符号。
Ubuntu中
- Linux内核的全局符号表在
/usr/src/linux-headers-XXXXX-generic/Module.symvers
“
XXXXX
是内核版本
相当于可以在多个文件中共享的变量或函数,在一个文件中定义,可以在其他文件中使用
在程序中使用下面这个宏导出变量或函数符号,即便是static限定(作用域为当前程序文件)的变量也可以被导出
EXPORT_SYMBOL(变量或函数);
加载模块时给模块传参数
在程序中声明传递的参数
#include <linux/Moduleparam.h>
-
原型:
module_param(name,type,perm);//声明传类型为type的参数name module_param_arry(name,type,num_point,perm);//传一个元素个数为num_point的数组,数组元素类型为type module_param_string (name,string,len