Linux内核编程知识集锦
编译内核
下载源码
1 |
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git |
根据需要,切换分支。
安装工具
1 |
apt install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison |
配置内核
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
cd linux-stable # 使用当前系统内核配置 cp -v /boot/config-$(uname -r) .config # 使用图形化界面进行配置 make menuconfig # 使用字符界面配置 make config # 在现有的内核设置文件基础上建立一个新的设置文件,只会向用户提供有关新内核特性的问题, # 在新内核升级的过程 中,make oldconfig非常有用 make oldconfig # 自动的尽量选择 y 选项 make allyesconfig # 自动的尽量选择 m 选项 make allmodconfig |
你也可以手工直接编辑.config文件。每个选项都可以设置以下值之一:
取值 | 说明 |
y | 将相应特性构建到内核中 |
n | 不包含此特性 |
m |
构建为模块,这样可以按需加载 注意:
|
编译内核
1 2 3 4 5 |
# 编译 make -j 8 # 编译bzImage make bzImage |
内核文件格式
格式 | 说明 |
vmlinux | 编译出来的最原始的内核文件,未压缩 |
zImage | zImage是ARM Linux常用的一种压缩映像文件,是vmlinux经过gzip压缩产生的 |
bzImage | bz表示big zImage,和zImage的区别是,zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么采用zImage或bzImage都行,如果比较大应该用bzImage |
uImage | uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的头,说明这个映像文件的类型、加载位置、生成时间、大小等信息。换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别 |
vmlinuz | 是bzImage/zImage文件的拷贝或指向bzImage/zImage的链接 |
initrd | initramfs |
安装内核
1 2 3 4 |
# 安装内核模块到系统 sudo make modules_install # 安装内核到系统 sudo make install |
更新initramfs,指向最新的内核:
1 |
sudo update-initramfs -c -k 4.15.0 |
更新GRUB BootLoader:
1 |
sudo update-grub |
重启后就可以使用新内核了。
调试内核
编译内核
设置内核选项:
1 2 3 4 5 6 7 8 9 10 11 12 |
make O=build/ defconfig make O=build/ menuconfig # Processor type and features ----> # [ ] Randomize the address of the kernel image (KASLR) # Kernel hacking ---> # [*] Kernel debugging # Compile-time checks and compiler options ---> # [*] Compile the kernel with debug info # [*] Provide GDB scripts for kernel debugging |
然后按正常流程构建。
阅读源码
使用Clion
内核项目本身是基于make的,我们需要将其转换为CMake项目。
首先,安装scan-build
1 2 3 |
sudo -H pip install scan-build # 或者 sudo apt install bear |
这是一个构建拦截工具(build interceptor) ,它能够拦截make的构建过程,并生成一个 compile_commands.json文件。这个文件叫JSON Compilation Database,这种文件格式描述了如何独立于某种构建系统,来Replay编译过程。
拦截构建过程:
1 2 3 4 5 6 7 8 |
cd linux-stable intercept-build make -j8 # 或者 bear make -j8 # 拦截其它目标 bear make tools/all bear make bzImage |
从compile_commands.json生成CMakeList.txt文件:
1 2 3 4 |
cd .. git clone https://github.com/habemus-papadum/kernel-grok.git cd linux-stable ../kernel-grok/generate_cmake |
如果报头文件找不到的错误,在CMakeList.txt中增加:
1 2 3 |
set(CMAKE_C_COMPILER "gcc") include_directories(".") include_directories("./include") |
使用VSCode
首先配置并编译好内核,然后在源码目录下执行:
1 2 3 4 5 6 |
git clone https://github.com/amezin/vscode-linux-kernel.git .vscode # 生成compile_commands.json python .vscode/generate_compdb.py # 如果不是编译的x64内核,则修改c_cpp_properties.json的intelliSenseMode。可选值: # gcc-x86 gcc-x64 gcc-arm gcc-arm64 |
Leave a Reply