Centos的源代码
http://vault.centos.org//7.0.1406/os/Source/SPackages/
标准的Linux Kernel
https://www.kernel.org/
查看内核导出的符号表
cat /proc/kallsyms
下载源代码:
wget http://vault.centos.org//7.0.1406/os/Source/SPackages/kernel-3.10.0-123.el7.src.rpm
解压:
rpm2cpio kernel-3.10.0-123.el7.src.rpm |cpio -div
默认在/usr/src放有一份kernel的头文件,这样在不需要下载整个内核源代码的情况下就可以编译自己编写的内核模块。
获取系统当前的config
cp /boot/config-3.10.0-123.el7.x86_64 .config 和make oldconfig生产的config一致
也可以make menuconfig来配置。
打补丁
patch -p1 < scst_exec_req_fifo-3.10.patch
编译&安装
make -j8;make modules; make modules_install;make install;
make modules_install 会把编译的ko放到/lib/modules/3.10.0-123.el7.x86_64/下
查看某个模块在那个路径下:
[root@bogon 2.6.32-358.18.1.el6.x86_64]# modinfo qla2xxx
filename: /lib/modules/2.6.32-131.0.15.el6.x86_64/kernel/drivers/scsi/qla2xxx/qla2xxx.ko
将自己编译的ko放到/lib/modules/2.6.32-131.0.15.el6.x86_64/kernel/drivers/scsi/qla2xxx/qla2xxx.ko;
make install的output
[root@localhost linux-3.10.0-123.el7]# make install
sh /root/SCST/linux-3.10.0-123.el7/arch/x86/boot/install.sh 3.10.0 arch/x86/boot/bzImage \
System.map "/boot
/root/SCST/linux-3.10.0-123.el7/arch/x86/boot/install.sh 这个脚本做的事情很简单,把bzImage和System.map放到放到boot下。
安装内核的过程主要完成了以下的工作:
1.将编译内核时生成的内核镜像bzImage拷贝到/boot目录下,并将这个镜像命名为vmlinuz-3.0.4。如果使用x86的cpu,则该镜像位于arch/x86/boot/目录下(处于正在编译的内核源码下)。
2.将~/linux-3.0.4/目录下的System.map拷贝到/boot/目录下,重新命名为System.map-3.0.4。该文件中存放了内核的符号表。
3.将~/linux-3.0.4/目录下的.config拷贝到/boot/目录下,重新命名为config-3.0.4。
4. 安装内核modules到/lib/modules下
5.创建initrd.img
initrd.img即为初始化的ramdisk文件,它是一个镜像文件,将一些最基本的驱动程序和命令工具打包到镜像文件里。该镜像文件的作用是在系统还没有挂载根分区前,系统需要执行一些操作,比如挂载scsi驱动,此时将initrd文件释放到内存中,作为一个虚拟的根分区,然后执行相关脚本,运行insmod命令加载需要的模块。
mkinitramfs 3.0.4 -o /boot/initrd.img-3.0.4
6. 更新grub
update-grub2
关于GRUB
默认安装会更新grub
/etc/grub2.cfg -> ../boot/grub2/grub.cfg
至于启动那个linux镜像,由/etc/default/grub的GRUB_DEFAULT=saved来决定;
其意思是上一次使用的value;
修改内核默认启动项
grub2-set-default 0
注:默认新安装的内核是第0项
清理编译的配置和文件
# make clean Delete most generated files Leave enough to build external modules
# make mrproper Delete the current configuration, and all generated files
# make distclean Remove editor backup files, patch leftover files and the like
启动之后查看大的patch是否成功,可以通过查看内核符号表来
cat /proc/kallsyms |grep blk_rq_map_kern_sg
关于kernel auto loadmodule and not load module on boot
https://wiki.archlinux.org/index.php/kernel_modules
在配置文件加入/etc/modprobe.d/modulename.conf中
加入 nvme 将会自动load nvme
加入blocklist name,将不会自动load
其他几个地方也可以加载模块:
/etc/sysconfig/modules
/etc/rc.local
/etc/rc.d/rc.local
/etc/modules: kernel modules to load at boot time.
编译一部分内核代码
make driver/usb/serial
make M=driver/usb/serial
make drivers/usb/serial/visor.ko
或者指定内核路径
make -C /home/user/rpmbuild/BUILD/kernel-3.10.0-123.el7/linux-3.10.0-123.el7.x86_64/ M=`pwd` modules
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int __init hello_init(void){
printk(KERN_ALERT "hello from hello world/n");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_ALERT "goodbye from hello world/n");
}
module_init(hello_init);
module_exit(hello_exit);
--------------------------------------------------------
编写一个Makefile,内容如下:
-------------------Makefile-----------------------
obj-m:=hello.o
----------------------------------------------------
然后使用如下命令编译
$make -C $HOME/Software/linux-kernel-2.6.31 M=`pwd` modules