Linux 内核碎碎念
在《Linux 内核简介》中我们介绍了 Linux 内核的一些特性: 单内核
、 ramdisk
以及 模块化
。下面分别从 内核信息获取
、 内核模块加卸载
、 ramdisk 文件管理
以及 /proc
和 /sys
目录来具体说说对 Linux 内核部分功能的管理和操作。
Linux 的核心虽然是 单内核
,但是它借鉴了 微内核
的设计,为内核引入了模块化机制。所以 Linux 内核其实是分为两部分组成: 内核核心
( kernel
)和 内核对象
( kernel object
)。其中 内核对象
也就是 内核模块
。内核模块与内核核心版本一定要严格匹配。
《内核编译初步》里面粘贴过一张内核配置图:

其中选项前面的 *
就意味着该功能编译进内核核心, M
意味着将该功能编译进内核模块,很多功能都可以自由选择。
编译进内核核心的功能可以在内核加载时直接启动,编译进内核模块的功能需要加载模块后启动,但是这个时间差,几乎可以忽略不计。而且将功能编译进内核模块还有个好处,就是可以动态装载和卸载,当某功能模块需要重新加载或者升级时,无需重新编译内核,只需要重新编译此模块的源码,然后手动装载即可。
内核信息获取
内核信息获取最常用的方式是使用 uname
命令:
[hzz@magedu ~]$ uname -a
Linux magedu 2.6.39-magedu-hzz #2 SMP Tue Oct 31 19:53:34 CST 2017 x86_64 x86_64 x86_64 GNU/Linux
[hzz@magedu ~]$ uname -r
2.6.39-magedu-hzz
[hzz@magedu ~]$ uname -n
magedu
[hzz@magedu ~]$
也可以到 /boot
目录去查看内核文件来获取内核版本号:
[hzz@magedu ~]$ ls /boot/ |grep vmlinuz-
vmlinuz-2.6.32-431.el6.x86_64
vmlinuz-2.6.39-magedu-hzz
[hzz@magedu ~]$
模块信息获取和管理
内核模块一般存在于 /lib/modules/VERSION-release/
下面,比如:
[hzz@magedu ~]$ ls /lib/modules/2.6.39-magedu-hzz/
build modules.alias.bin modules.dep modules.inputmap modules.order modules.symbols source
kernel modules.builtin modules.dep.bin modules.isapnpmap modules.pcimap modules.symbols.bin
modules.alias modules.ccwmap modules.ieee1394map modules.ofmap modules.seriomap modules.usbmap
[hzz@magedu ~]$
但是我们一般不会手动管理,而是通过工具去查看和加卸载。
模块查看
lsmod
Show the status of modules in the Linux Kernel.
顾名思义,列出并查看模块信息,没有参数,直接执行即可。
[hzz@magedu ~]$ lsmod
Module Size Used by
ipt_REJECT 2472 2
nf_conntrack_ipv4 9136 2
nf_defrag_ipv4 1505 1 nf_conntrack_ipv4
iptable_filter 1746 1
ip_tables 20183 1 iptable_filter
ip6t_REJECT 4534 2
nf_conntrack_ipv6 8271 2
nf_defrag_ipv6 10359 1 nf_conntrack_ipv6
xt_state 1354 4
nf_conntrack 79401 3 nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state
ip6table_filter 1719 1
ip6_tables 20441 1 ip6table_filter
ipv6 328832 77 ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6
...
[hzz@magedu ~]$
modinfo
Show information about a Linux Kernel module.
modinfo
是查看模块详细信息的命令,一般是配合 lsmod
找出模块名称后,再进行详细信息查看。
[hzz@magedu ~]$ modinfo ext4
filename: /lib/modules/2.6.39-magedu-hzz/kernel/fs/ext4/ext4.ko
license: GPL
description: Fourth Extended Filesystem
author: Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others
srcversion: 2995D9485257598B39ECC37
depends: mbcache,jbd2
vermagic: 2.6.39-magedu-hzz SMP mod_unload modversions
[hzz@magedu ~]$
模块的加载和卸载
modprobe
Add and remove modules from the Linux Kernel.
内核模块装载和卸载工具。
# 卸载内核模块
[hzz@magedu ~]$ lsmod|grep dm_mirror
dm_mirror 14348 0
dm_region_hash 10907 1 dm_mirror
dm_log 9798 2 dm_mirror,dm_region_hash
dm_mod 75833 11 dm_mirror,dm_log
[hzz@magedu ~]$ sudo modprobe -r dm_mirror
[hzz@magedu ~]$ lsmod|grep dm_mirror
[hzz@magedu ~]$
# 装载内核模块
[hzz@magedu ~]$ sudo modprobe dm_mirror
[hzz@magedu ~]$ lsmod|grep dm_mirror
dm_mirror 14348 0
dm_region_hash 10907 1 dm_mirror
dm_log 9798 2 dm_mirror,dm_region_hash
dm_mod 75833 11 dm_mirror,dm_log
[hzz@magedu ~]$
insmod 和 rmmod
insmod is a trivial program to insert a module into the kernel. Most users will want to use modprobe(8) instead, which is more clever and can handle module dependencies.
装卸载内核模块的另一组命令,但是需要手动关联和装载依赖模块。和 modprobe
的区别就跟 rpm
和 yum
的区别类似,建议使用 modprobe
对模块进行管理。
depmod
Generate modules.dep and map files.
内核模块依赖关系文件的生成工具,不常用,在此先不做介绍。
ramdisk 文件管理
ramdisk 是一个辅助文件,不是必须的,取决于内核是否能直接驱动系统所在的硬盘设备。
ramdisk 是一个简装版的根文件系统,用于在内存中展开,加载速度很快。
ramdisk 存在于 /boot
下面:
[hzz@magedu ~]$ ls /boot/|grep initramfs
initramfs-2.6.32-431.el6.x86_64.img
initramfs-2.6.39-magedu-hzz.img
[hzz@magedu ~]$
如果不小心将 ramdisk 文件删掉了,该怎么办呢?
mkinitrd
mkinitrd - is a compat wrapper, which calls dracut to generate an initramfs.
通过调用 dracut
来创建 ramdisk 的命令。
比如,为当前使用中的内核重新制作 ramdisk 文件:
# 删除当前内核的 ramdisk 以便试验
[hzz@magedu ~]$ sudo rm -f /boot/initramfs-$(uname -r).img
[hzz@magedu ~]$ ls /boot/|grep initramfs
initramfs-2.6.32-431.el6.x86_64.img
[hzz@magedu ~]$
# 重新创建 ramdisk 文件
[hzz@magedu ~]$ sudo mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
[hzz@magedu ~]$ ls /boot/|grep initramfs
initramfs-2.6.32-431.el6.x86_64.img
initramfs-2.6.39-magedu-hzz.img
[hzz@magedu ~]$
mkinitrd
还有两个参数比较常用:
--with= # 除了默认的模块之外需要装载至 initramfs 中的模块;
--preload= # initramfs 所提供的模块需要预先装载的模块;
dracut
low-level tool for generating an initramfs image.
一个比较底层的 ramdisk 文件创建工具, mkinitrd
也是通过调用这个命令来创建 ramdisk 文件的,所以使用方式上类似。建议使用 mkinitrd
来操作。
dracut /boot/initramfs-$(uname -r).img $(uname -r)
内核信息输出的伪文件系统
/proc
内核状态和统计信息的输出接口,从这里面的文件可以看到系统运行时的各种状态以及配置信息(比如 cpuinfo 和 vmstat )。虽然都是文件,但其实是个输出接口,让其他程序可以从此处读取系统状态,故称为 伪文件系统
。里面的文件大都只读,也就是只能看,即使改了也没有任何意义,除了 sys
文件夹。
/proc/sys
/proc/sys
目录是内核功能特性配置的文件夹,可通过编辑里面的文件来实现临时更改内核某个功能的特性,比如释放缓存的操作为 echo 1 > /proc/sys/vm/drop_caches
,但是直接用文件系统命令或者重定向的方式来直接更改 /proc/sys
里面的文件,只能是在当前运行的内核中有效,内核重启后失效。若需要将配置永久生效,有两种方式可实现。
sysctl 命令
专用于查看或设定 /proc/sys
目录下参数的值。
可以使用 -a
参数查看所有参数的值,也可以指定参数查看。比如我们想查看 /proc/sys/net/ipv4.icmp_echo_ignore_all
的值:
[hzz@magedu vm]$ sysctl net.ipv4.icmp_echo_ignore_all
net.ipv4.icmp_echo_ignore_all = 0
[hzz@magedu vm]$
可以看到, /proc/sys/net/ipv4.icmp_echo_ignore_all
其实就是 net.ipv4.icmp_echo_ignore_all
的虚拟文件路径,改动 net.ipv4.icmp_echo_ignore_all
才能让配置永久生效。
使用 -w
选项,即可改变内核功能配置。比如我们要实现主机禁 ping ,可以使用以下命令:
[hzz@magedu ~]$ sudo sysctl -w net.ipv4.icmp_echo_ignore_all=1
net.ipv4.icmp_echo_ignore_all = 1
[hzz@magedu ~]$
# 注意赋值时等号左右不要有空格
修改配置文件
修改 /etc/sysctl.conf
和 /etc/sysctl.d/*.conf
配置文件,也可以实现重启内核后保留自定义内核配置。这个很容易理解,直接在文件中添加参数和值即可:
[hzz@magedu ~]$ more /etc/sysctl.conf
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
# Controls IP packet forwarding
net.ipv4.ip_forward = 0
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1
# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1
...
修改文件后是不能立即生效的,需要重启系统。若要立即生效,可使用以下命令:
sysctl -p /etc/sysctl.conf
/sys
这个目录平时接触和修改的机会比较小,网上也有很多相关资料,这里只是粗略地介绍一下。
/sys
目录是一个独立的文件系统,称为 sysfs
。
sysfs
的作用是输出内核识别出的各硬件设备的相关属性信息,也有内核对硬件特性的可设置参数,对此些参数的修改,即可定制硬件设备工作特性。
udev
通过读取 /sys
目录下的硬件设备信息按需为各硬件设备创建设备文件。
udev
是用户空间程序,专用工具: devadmin
, hotplug
。
udev
为设备创建设备文件时,会读取其事先定义好的规则文件,一般在 /etc/udev/rules.d/
目录下,以及 /usr/lib/udev/rules.d/
目录下。