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