kernel定制,编译内核
一,准备开发环境
1,包组:Development Tools,Server Platform Development
2,包:ncurses和ncurses-dev
3,如果是图形界面,则需要额外的GTK或者QT的包组。
二,获取目标主机上硬件设备的相关信息
1,获取cpu的信息
cat /proc/cpuinfo
方法2:
# lscpuArchitecture: x86_64CPU op-mode(s): 32-bit, 64-bitByte Order: Little EndianCPU(s): 4On-line CPU(s) list: 0-3Thread(s) per core: 1Core(s) per socket: 4Socket(s): 1NUMA node(s): 1Vendor ID: GenuineIntelCPU family: 6Model: 142Model name: Intel(R) Core(TM) i5-8350U CPU @ 1.70GHzStepping: 10CPU MHz: 1896.003BogoMIPS: 3792.00Hypervisor vendor: KVMVirtualization type: fullL1d cache: 32KL1i cache: 32KL2 cache: 256KL3 cache: 6144KNUMA node0 CPU(s): 0-3
方法3:详细显示cpu信息。
# yum install x86info# x86info -a
2,获取pci总线上的设备信息
显卡,网卡,鼠标,键盘都是连的pci总线。
详细-v:显示显示。
# lspci00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]00:01.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)00:02.0 VGA compatible controller: VMware SVGA II Adapter00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service00:05.0 Multimedia audio controller: Intel Corporation 82801AA AC'97 Audio Controller (rev 01)00:06.0 USB controller: Apple Inc. KeyLargo/Intrepid USB00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)00:08.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)00:0d.0 SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)# lspci -v
3,获取usb设备信息
# lsusbBus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
4,获取磁盘设备信息
# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 60G 0 disk├─sda1 8:1 0 1G 0 part /boot└─sda2 8:2 0 59G 0 part ├─centos-root 253:0 0 37G 0 lvm / ├─centos-swap 253:1 0 3.9G 0 lvm [SWAP] └─centos-home 253:2 0 18.1G 0 lvm /homesdb 8:16 0 1G 0 disksdc 8:32 0 1G 0 disksdd 8:48 0 1G 0 disk└─sdd1 8:49 0 900M 0 partsr0 11:0 1 1024M 0 rom
5,获取全部硬件设备信息,类似windows的资源管理器
# hal-device
三,编译内核
1,获取内核源代码
本机内核是linux-3.10.0
# wget http://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.10.67.tar.xz
内源码放在/usr/src下
# tar xf linux-3.10.67.tar.xz -C /usr/src# ls /usr/srcdebug kernels linux-3.10.67
当缺少设备驱动时,我们要编译内核源码,以获得驱动。
为什么编译内核就能获得驱动呢?
内核的源代码,基本包括所有硬件的驱动,但是我们安装的系统也是编译出来的,编译的时候没有包含你要用的驱动的源代码。所以只要在编译的时候,把你要的驱动的源代码包含进来,编译出来的系统就支持你要的设备了。当然前提是,kernel源代码里有你要的驱动的代码,如果没有,那么再怎么编译内核也得不出你要得驱动。
这时编译会去找/usr/src/linux目录,但是没有此目录,只有/usr/src/linux-3.10.67目录,不要直接修改linux-3.10.67目录的名字,建立符号链接。
理由是:当又有新版本进来时,直接把符号链接改到新版本上就号,这样一来,新版本不好用了,修改符号链接,还能执行旧的
# ln -sv linux-3.10.67 linux‘linux’ -> ‘linux-3.10.67’# ls linuxarch CREDITS drivers include Kbuild lib mm REPORTING-BUGS security usr block crypto firmware init Kconfig MAINTAINERS net sound virt Documentation fs ipc kernel Makefile
目录arch里,基本包括了所有架构的cpu:
# ls linux-3.10.67/arch/alpha arm64 c6x h8300 Kconfig metag mn10300 powerpc sh um xtensaarc avr32 cris hexagon m32r microblaze openrisc s390 sparc unicore32arm blackfin frv ia64 m68k mips parisc score tile x86
目录block里,块设备驱动:
# ls linux-3.10.67/block/blk-cgroup.c blk.h blk-map.c blk-tag.c cfq-iosched.c ioctl.c
目录crypto里,加密算法:
# ls linux-3.10.67/crypto842.c asymmetric_keys cipher.c eseqiv.c md4.c scatterwalk.c twofish_common.c
目录Documentation里,kernel的文档
# ls linux-3.10.67/Documentation/
目录drivers里,基本上包括了所有设备的驱动:
# ls linux-3.10.67/drivers/accessibility cdrom dma hwmon isdn message parisc pwm
firmware目录,主板固件驱动:
# ls linux/firmware/3com bnx2x emi26 korg ositech tehuti
fs目录,文件系统:
# ls linux/fs9p block_dev.c drop_caches.c fs_struct.c Kconfig.binfmt ocfs2
init目录,/sbin/init程序:
# ls linux/initcalibrate.c do_mounts.h do_mounts_md.c initramfs.c Kconfig Makefile version.cdo_mounts.c do_mounts_initrd.c do_mounts_rd.c init_task.c main.c noinitramfs.c
ipc目录,进程间通信:
# ls linux/ipccompat.c ipcns_notifier.c Makefile mqueue.c msgutil.c sem.c syscall.c util.hcompat_mq.c ipc_sysctl.c mq_sysctl.c msg.c namespace.c shm.c util.c
kernel目录,内核自己
lib目录,库
mm目录目录:内存管理
net目录目录:网络管理
samples目录:实例
scripts目录:编译时,安装时使用的脚本
security目录:安全相关
sound目录:声音相关
tools目录:工具
virt目录:虚拟化
# ls linux/virt/kvm
2,获取make帮助:
cd进入/usr/src/linux目录,执行make help
获取帮助
....Configuration targets: config - Update current config utilising a line-oriented program nconfig - Update current config utilising a ncurses menu based program menuconfig - Update current config utilising a menu based program....
3,配置kernel安装选项,类似源码安装里的configure
# make menuconfig
如果没有安装ncurses-devel会出错误:unable to find the ncurses library,所以需要安装:yum install ncurses-devel
执行成功后,显示menu界面:
配置内核安装选项过于复杂,找个模板使用,centos的/boot目录下有个文件:config-3.10.0-957.el7.x86_64。
此文件是,centos做的配置文件,可以参考使用。
make menuconfig执行后,会在/usr/src/linux/目录下生成.config文件,所以我们不做make menuconfig了,直接把config-3.10.0-957.el7.x86_64复制从.config文件。
# cp /boot/config-3.10.0-957.el7.x86_64 /usr/src/linux/.config# cat /usr/src/linux/.configCONFIG_64BIT=yCONFIG_X86_64=yCONFIG_X86=yCONFIG_INSTRUCTION_DECODER=yCONFIG_OUTPUT_FORMAT="elf64-x86-64"...
支持在已有的.config文件基础上进行修改
make config:基于命令行,以遍历的方式配置。(输入yes,no等)
make menuconfig:基于curesesd的文本界面配置
make gconfig:基于GTK桌面开发环境的界面进行配置
make xconfig:基于QT桌面开发环境的界面进行配置
支持从0开始配置
make defconfig:基于内核为目标平台提供的默认配置为模板进行配置
make allnoocnfig:所以选项均为no
centos做的配置文件,有很多是用不到的,再使用make menuconfig,关闭不要的功能。
# make menuconfig
[ ]:不编译,不使用
[M]:编译成模块,不编译进内核
[*]:直接编译进kernel
(1)修改cpu:
默认的cpu驱动是General-x86-64。是通用的驱动,但不能完全发挥酷睿cpu的作用,所以修改成core(酷睿)
修改后:
(2)添加release号
(3)关闭蓝牙功能:
(4)添加ntfs文件系统的驱动(默认配置里是没有添加ntfs的):
4,编译内核:make [-j #]
。多核心可以使用-j,指定编译线程的数量,编译非常消耗cpu。
由于编译很花时间,如果是远程连接的话,ssh万一断开了,编译一般就前功尽弃了。所以要利用一个叫screen的工具。
screen的好处是,当ssh断开后,编译还会继续。
screen安装:
yum install screen
在终端上打开一个screen:
screen
从screen回到终端:ctrl+a d
查看打开了哪些scren:
screen -ls
从终端回到screen:
screen -r screen号
终止screen:在screen里面输入:
exit
使用screen编译:
# screen进入了screen,在screen里执行编译# make -j 4
编译时,可以退出screen。在终端使用'htop'看看,发现cpu基本都是100%运行了。
部分编译:当发现漏了某个模块或者驱动等,我们不需要重新编译,只需编译缺少的部分,部分编译的方法:
只编译某子目录种的相关代码:
# cd /usr/src/linux# make path/to/dir/
只编译一个特定的模块
# cd /usr/src/linux# make path/to/dir/file.ko
file其实是xxxx.c,要把.c去掉,换成.ko
交叉编译:目标平台与当前正在执行编译所在的平台不同。
# make ARCH=arch_name
获取特定目标平台的使用帮助:
# make ARCH=arch_name help
arch_name可以是arm等。
如何在执行过编译的内核源码目录上做重新编译?
需要先执行清理:
make clean:删除编译生成的绝大多数文件,但保留.config
make mrproper:删除编译生成的绝大多数文件,也删除.config
make distclean:基本删除所有。
然后从新编译。
5,安装模块(modules):make modules_instal
模块安装完成后,在目录/lib/modules里多出3.10.67-1.el7。【-1.el7】是在配置编译选项是加的。
# ll /lib/modulestotal 4drwxr-xr-x. 8 root root 4096 Feb 23 09:18 3.10.0-957.el7.x86_64drwxr-xr-x. 3 root root 91 Feb 23 22:14 3.10.67-1.el7
6,安装内核:make install
。会自动生成grub
安装成功后,在boot目录生成了:
kernel:vmlinuz-3.10.67-1.el7
ramdisk:initramfs-3.10.67-1.el7.img
各种映射:System.map-3.10.67-1.el7
# ls -lrt /boot-rw-r--r--. 1 root root 4776128 Feb 23 22:18 vmlinuz-3.10.67-1.el7-rw-r--r--. 1 root root 2828222 Feb 23 22:18 System.map-3.10.67-1.el7lrwxrwxrwx. 1 root root 27 Feb 23 22:18 vmlinuz -> /boot/vmlinuz-3.10.67-1.el7lrwxrwxrwx. 1 root root 30 Feb 23 22:18 System.map -> /boot/System.map-3.10.67-1.el7-rw-------. 1 root root 48045100 Feb 23 22:19 initramfs-3.10.67-1.el7.img
并且在/etc/grub2.cfg文件里多出了:
### BEGIN /etc/grub.d/10_linux ###menuentry 'CentOS Linux (3.10.67-1.el7) 7 (Core)' --class cento
7,重启系统选择新的内核。
# c/c++ 学习互助QQ群:877684253![](https://img2018.cnblogs.com/blog/1414315/201811/1414315-20181106214320230-961379709.jpg)# 本人微信:xiaoshitou5854