Linux内核设计风格
单内核:所有内核功能都做进内核由一个进程运行。
Linux是单内核但是采用了微内核的思想由核心+.ko内核模块(文件系统模块,驱动模块,网络模块,加密模块,arch)组成以此来解决kernel过大的问题,开机加载只加载核心内核到内存如果在需要用到其它驱动或是文件系统在到/lib/modules/下加载即可。
/lib/modules/”内核版本号命令的目录”:存放各种内核模块的目录。
Linux这样构建内核虽然可以缩减内核,但是也有其它问题比喻当核心内核加载到内存之后,内核需要加载rootfs而rootfs在硬盘上存放这呢?所以内核要是想加载到rootfs就需要能够驱动硬盘和文件系统,而驱动和文件系统又被做为内核模块放在根下就成为了这样加载rootfs就要先加载驱动和文件系统,而加载文件系统和驱动就要先加载到rootfs、解决方法。
1.把需要的驱动和文件系统直接编译进核心内核。
2.在核心内核和rootfs之间提供一个文件(RHEL5:initrd ,RHEL6:initramfs);这个文件负责提供rootfs的驱动和文件系统给内存中的核心内核;这个文件不是提前编译好的,而是安装程序知道rootfs的驱动在最后一个步骤利用脚本动态生成的这个文件。当这个文件生成之后内核文件该如何访问呢?其实这个文件也是一个虚根只是内核文件跟rootfs之间的一个过渡文件,当内核从这个文件中得到可以访问rootfs的驱动和文件系统时就会产生根切换进而转到真正的rootfs中然后再加载/sbin/bash。
微内核:所有内核功能都做成子功能需要时调用;windows,Solaris并真正支持线程。
什么是内核启动参数
首先我们知道软件是有参数的,而软件工程师们肯定知道很多函数式有参数的。这个世界怎么这么多参数?人们在这个世界极度缺少”先知”这种珍惜资源的情况下,只能用试错这种方法来解决遇到的问题。久而久之就发明了参数这个东西。所以参数是可以乱变得,错了就变,直到对了位置。既然Linux的开发者们跟我们是一个世界里的人,也无法保证Linux内核可以解决所有问题,所以让Linux内核支持启动参数。
所谓内核启动参数,就一定是在Linux内核启动的时候传给它的参数。否则就是内核运行时参数了。其主要目的是,当内核无法识别某些硬件导致不能设置硬件参数时,或者不希望内核更改某些参数值时,抑或希望内核表现某些特性时,让Linux内核具备人工干预的途径。这也是必须选择GRUB等Bootloader去启动Linux的具有绝对杀伤力的理由。因为直接让BIOS加载Linux内核将无法传递任何启动参数。
常见的内核启动参数
init=……….:设置init进程的位置,如果没有明确给出这个参数,内核会按照/etc/init、/bin/init、/sbin/init、/bin/sh这个顺序来搜索,如果没找到,Linux就会宕机。
root=………:该参数告诉内核启动时使用哪个磁盘分区作为根文件系统。比如可以指定根文件系统为/dev/sda5:root=/dev/hda8。这个参数必须指定,否则Linux将无法正常工作,甚至因为找不到init进程而宕机。
ro和rw:该参数告诉内核启动时如何挂接根文件系统。ro参数告诉内核以只读方式挂接根文件系统,这样可以有效防止根文件系统被破坏。另外,如果在启动时需要对根文件系统进行fsck,则必须以只读方式挂接。rw正好与ro相反,允许读写根文件系统的内容。如果不指定这个参数,则默认是ro。
mem=………..:限制或设定内核使用的内存数量。
initrd=………..:指定内核初始化用ramdisk的位置。这个功能非常有用。后面会说。
quiet:quiet参数是让内核采用静默方式启动,即尽量少输出启动信息。
nosmp和maxcpus=N:这两个参数只有在拥有多颗CPU的时候才起作用。nosmp参数用来禁止开启支持多个CPU的功能。maxcpus则是限制最多支持的CPU个数。现在人们都巴不得使用smp技术来提高运算速度,nosmp主要用在linux运行在虚拟机上的时候会出现计时不准确的情况。
由于Linux的内核启动参数太多,举不胜举。这里也就不多说了。且以上所有参数都是在内核启动之前就应该指定的,否则就会无法启动,或者得不到预想的效果。这也正好说明了它们是内核启动参数而不是内核运行时参数了。正所谓唇齿相依,Linux内核是齿,则内核启动参数就是唇。如果内核启动参数设定不当,内核也很难正常工作。唇亡且有齿不寒之理?至于这些参数放在什么地方、内核怎么处理、如何处理、何时处理等问题。有兴趣可以自行阅读内核源代码。
调整内核参数
在/proc,/sys这两个目录下的文件一般都是只读的,此目录内是没有文件的只有当系统开机后所产生的内核信息会存储在里面。而/proc/sys这个目录下的目录中的文件一般是管理员可修改的用来调整内核参数的。
立即生效方式,如:
1)临时清除内存中的buffer和cache
1 2 3 |
[root@localhost ~]# echo "1" > /proc/sys/vm/drop_caches 或 [root@localhost ~]# sysctl -w vm.drop_caches=1 |
2)临时修改主机名
1 2 3 |
[root@localhost ~]# echo "www.baidu.com" > /proc/sys/kernel/hostname 或 [root@localhost ~]# sysctl -w kernel.hostname="baidu.com" |
3)临时开启路由功能
1 |
[root@localhost ~]# sysctl -w net.ipv4.ip_forward=1 |
永久生效方式,如:
第一步:修改内核参数配置文件
1 2 |
[root@localhost ~]# vi /etc/sysctl.conf net.ipv4.ip_forward=1 |
第二步:重读内核文件/etc/sysctl.conf使之立即生效
1 |
[root@localhost ~]# sysctl -p |
第三步:查看内核所有参数 ,确定修改参数生效了
1 2 |
[root@localhost ~]# sysctl -a | grep net.ipv4.ip_forward net.ipv4.ip_forward = 1 |
内核模块管理命令
1 2 3 4 5 6 7 |
lsmod #列出当前所有内核模块 modprobe MOD_NAME #装载内核模块只需指定模块名称 modprobe -r MOD_NAME #卸载内核模块 insmod /PATH/TO/MOD_NAME #装载内核模块需要指定模块路径 rmmod MOD_NAME #卸载内核模块 modinfo MOD_NAME #查看模块详细信息 depmod /PATH/TO/MODULE_DIR #查看目录下的模块间的依赖关系 |
内核中的功能除了核心功能之外,在编译时大多数有三种选择
1)不使用此功能
2)编译成内核模块
3)编译进内核
手动编译内核
一、准备内核源码
1 2 |
[root@localhost ~]# ln -s /usr/src/linux-2.6.32-10 /usr/src/linux [root@localhost ~]# cd /usr/src/linux |
二、产生一个.config的配置文件(要用这个文件进行定制内核)
1 |
[root@localhost linux]# make allnoconfig |
我们自行产生.config文件进行编译时,根据系统性能时间不等且容易出错;所以一般先可以使用CentOS提供的config-2.6.32-431.el6.x86_64配置文件,复制到要编译的内核目录下改名为.config,然后再根据这个文件进行定制修改即可。不容易出错这样,就不需要自己make出一个.config的配置文件了。直接复制系统提供的。
1 |
[root@localhost linux]# cp /boot/config-2.6.32-431.el6.x86_64 .config |
三、开始定制内核编译选项
既然编译内核,那么肯定需要编译工具,所以需要安装开发工具。
1 |
[root@localhost ~]# yum groupinstall "Development tools" |
在编译内核时,有多种编译方式的选择,我们只需要选择一种编译方式即可。
第一种:使用gnome桌面环境编译,需要安装桌面开发环境,包名”Desktop Platform Development”
1 |
[root@localhost ~]# make gconfig |
第二种:使用kde桌面环境编译
1 |
[root@localhost ~]# make dconfig |
第三种:一条条遍历选择内核参数
1 |
[root@localhost ~]# make config |
第四种:以文本菜单界面编译内核,推荐使用
1 |
[root@localhost ~]# make menuconfig |
使用menuconfig界面编译时出现的符号含义说明:
1 2 3 4 |
[*]:表示把此功能做进内核 [M]:表示把此功能做成模块 [ ]:空白表示不启用此功能 ()local version – append to kernel release:自定义2.6.32-1.el5 |
四、开始编译内核
在编译时可选择编译有以下几种方式:
1)编译整个内核
1 |
[root@localhost linux]# make |
2)只编译某子目录下的相关代码
1 |
[root@localhost ~]# make SUBDIR=/arch |
3)只编译部分模块
1 |
[root@localhost ~]# make drivers/net/pcnet32.ko |
4)只编译某一个模块
1 |
[root@localhost ~]# make M=/drivers/net/ |
5)交叉编译(在X86架构上编译arm架构的内核)
1 |
[root@localhost ~]# make ARCH=arm |
如果在编译过程中出错了使用此命令清除配置
1 2 |
[root@localhost ~]# make clean [root@localhost ~]# make mrproper |
五、编译完成后,开始安装内核
1 2 3 4 |
[root@localhost ~]# make modules_install #先安装内核模块 [root@localhost ~]# make install #在安装内核 |
查看程序有哪些库文件
1 |
[root@localhost ~]# ldd /bin/bash |
上面的介绍只是说明了编译内核的一个大概流程跟命令,这里提供一个内核编译的案例:Iptables之七层过滤模块(六)