UNIX/Linux系统管理技术手册-读书笔记-第十一章
《UNIX/Linux系统管理技术手册-读书笔记-第十一章
驱动程序与内核
1. 内核概述
1.1 内核职责
| 功能 | 说明 |
|---|---|
| 硬件管理 | 通过驱动程序抽象硬件细节 |
| 进程/线程管理 | CPU分时、调度、进程间通信 |
| 内存管理 | 虚拟内存、地址空间、内存保护 |
| I/O设施 | 文件系统、网络接口、串口等 |
| 杂务(Housekeeping) | 启动、关机、定时器、多任务 |
核心理念:内核为硬件提供抽象接口,用户进程通过系统调用与内核交互,无需关心底层硬件细节。
1.2 内核版本
Linux内核版本:
- 语义化版本:主版本.次版本.补丁号
- 次版本号与稳定性无固定关系(旧规则已废弃)
- 发行版通常使用较旧但经过充分测试的内核版本
- 不建议手动将新内核硬装到现有发行版,应选择针对该内核设计的发行版
FreeBSD内核版本:
- 与操作系统统一版本号
- 两个主版本同时维护(如10.x稳定维护,11.x活跃开发)
- 大版本支持5年,小版本支持至下个大版本发布后3个月
|
|
2. 设备与驱动程序
2.1 设备文件与设备编号
| 概念 | 说明 |
|---|---|
| 设备文件 | /dev下的特殊文件,用户空间访问驱动程序的入口 |
| 主设备号(Major) | 标识设备类型/驱动程序 |
| 次设备号(Minor) | 标识设备实例或特定功能 |
| 块设备(b) | 按块读写(磁盘) |
| 字符设备(c) | 按字节读写(终端、串口) |
| 伪设备 | 无实际硬件,如/dev/null、/dev/zero、/dev/urandom、PTY |
查看设备号:
网络接口在
/dev无设备文件,使用独立的命名系统(如eth0、enp0s3)。
2.2 现代设备文件管理
| 平台 | /dev管理 | 用户态守护进程 | 配置目录 |
|---|---|---|---|
| Linux | devtmpfs(内核) | udevd | /etc/udev/rules.d/、/lib/udev/rules.d/ |
| FreeBSD | devfs(内核) | devd | /etc/devfs.conf、/etc/devfs.rules、/etc/devd.conf |
2.3 Linux设备管理(udev + sysfs)
sysfs(/sys):内核设备信息的虚拟文件系统,udevd的数据源。
/sys子目录 |
内容 |
|---|---|
block/ |
块设备(硬盘) |
bus/ |
总线类型(PCI-E、SCSI、USB) |
class/ |
按功能分类的设备(声卡、网卡) |
devices/ |
所有已发现设备的分层树 |
module/ |
已加载的内核模块 |
udevadm命令:
| 子命令 | 功能 |
|---|---|
udevadm info -a -n /dev/sdb |
查询设备所有属性(用于编写规则) |
udevadm monitor |
监视内核/udev事件 |
udevadm control --reload-rules |
重新载入规则(修改后执行) |
udevadm test /dev/sdb |
测试规则匹配 |
udev规则(/etc/udev/rules.d/*.rules):
格式:match_clause, ... assign_clause, ...
| 匹配键 | 作用 | 赋值键 | 作用 |
|---|---|---|---|
ACTION |
add/remove事件 | NAME |
设备文件名 |
KERNEL |
内核名称(如sd[a-z]) | SYMLINK |
符号链接 |
SUBSYSTEM |
子系统(block/usb) | RUN |
触发时执行的命令 |
ATTR{key} |
sysfs属性值 | OWNER/GROUP/MODE |
权限 |
ENV{key} |
环境变量 | ||
PROGRAM |
执行外部命令(匹配) |
USB闪存自动挂载规则示例:
# 识别 + 创建符号链接
ATTRS{model}=="USB2FlashStorage", KERNEL=="sd[a-z]1", SYMLINK+="ate-flash%n"
# 插入时挂载
ACTION=="add", ATTRS{model}=="USB2FlashStorage", KERNEL=="sd[a-z]1", \
RUN+="/bin/mount /dev/%k /mnt/ate-flash"
# 移除时卸载
ACTION=="remove", ATTRS{model}=="USB2FlashStorage", KERNEL=="sd[a-z]1", \
RUN+="/bin/umount -l /mnt/ate-flash"
2.4 FreeBSD设备管理
devfs.conf(静态/内置设备):
link cd0 dvd # 创建符号链接
own cd0 root:sysadmin # 设置所有权
perm cd0 0660 # 设置权限
devfs.rules(可移动设备规则,支持jail环境隐藏设备)
devd.conf(设备事件处理):
attach:设备接入时执行detach:设备移除时执行nomatch:无匹配规则时的兜底notify:内核事件响应
FreeBSD的自动挂载现在由
autofs处理,不再由devd负责。
3. 内核参数调优(sysctl)
3.1 Linux sysctl
| 命令 | 功能 |
|---|---|
sysctl -a |
列出所有可调参数 |
sysctl net.ipv4.ip_forward=1 |
临时设置(立即生效) |
sysctl -p |
从/etc/sysctl.conf加载参数(永久生效) |
常用Linux可调参数:
/proc/sys/路径 |
功能 |
|---|---|
fs/file-max |
系统最大打开文件数(数据库/Web服务器常需调大) |
kernel.ctrl-alt-del |
Ctrl+Alt+Del行为(0=忽略) |
kernel.panic |
内核恐慌后等待秒数(0=不重启) |
kernel.shmmax |
最大共享内存(Oracle等数据库关键) |
net.ipv4.ip_forward |
IP转发(路由器启用) |
net.ipv4.tcp_syncookies |
SYN泛洪防御 |
net.ipv4.ip_local_port_range |
本地端口范围(高并发服务器调大) |
net.ipv4.tcp_fin_timeout |
FIN超时(高并发调低至~20) |
vm.overcommit_memory |
内存超额行为控制 |
永久配置:编辑/etc/sysctl.conf
net.ipv4.ip_forward = 0
fs.file-max = 65535
kernel.shmmax = 68719476736
3.2 FreeBSD sysctl
| 参数 | 功能 |
|---|---|
net.inet.ip.forwarding |
IPv4转发 |
net.inet6.ip6.forwarding |
IPv6转发 |
kern.maxfiles |
最大文件描述符数 |
kern.ipc.nmbclusters |
网络mbuf cluster数(高网络负载调大) |
kern.maxvnodes |
vnode最大数(文件服务器调大) |
net.inet.tcp.blackhole |
关闭端口时是否回复RST(1/2=不回复,减缓扫描) |
net.inet.udp.blackhole |
关闭UDP端口是否回复ICMP不可达 |
4. 构建定制内核
4.1 Linux内核构建
| 步骤 | 命令 | 说明 |
|---|---|---|
| 1 | cd /usr/src/linux |
进入源码目录 |
| 2 | make menuconfig / make xconfig / make gconfig |
配置内核选项(推荐xconfig/gconfig) |
| 3 | make clean |
清理旧构建(可选但推荐) |
| 4 | make |
编译内核和模块 |
| 5 | make modules_install |
安装模块到/lib/modules/ |
| 6 | make install |
安装内核到/boot,更新GRUB |
配置选项值:
y= 编译进内核(内置,不可卸载)m= 编译为可装载模块(按需加载)n= 不包含
迁移旧配置:make oldconfig(新内核只问新增选项)
4.2 FreeBSD内核构建
配置文件位置:/usr/src/sys/arch/conf/(arch为amd64/i386等)
| 步骤 | 命令 |
|---|---|
| 1 | cd /usr/src/sys/arch/conf |
| 2 | cp GENERIC MYCUSTOM |
| 3 | 编辑MYCUSTOM(注释不需要的设备/选项) |
| 4 | cd /usr/src |
| 5 | make buildkernel KERNCONF=MYCUSTOM |
| 6 | make installkernel KERNCONF=MYCUSTOM |
配置文件格式:参考config(5)和config(8)手册页。
5. 可装载内核模块(LKM)
5.1 Linux模块管理
| 命令 | 功能 |
|---|---|
lsmod |
列出当前已装载模块 |
modprobe module |
装载模块(自动处理依赖) |
modprobe -r module |
卸载模块 |
modprobe -c |
显示当前配置(/etc/modprobe.conf) |
insmod module.ko |
底层装载(不处理依赖,不推荐) |
rmmod module |
底层卸载 |
模块参数传递:
|
|
配置文件:/etc/modprobe.conf或/etc/modprobe.d/*.conf
5.2 FreeBSD模块管理
| 命令 | 功能 |
|---|---|
kldstat |
列出已装载模块 |
kldload foo |
装载foo.ko |
kldunload foo |
卸载foo.ko |
kldstat -m foo |
查看模块状态 |
模块位置:/boot/kernel/(标准)、/boot/modules/(定制)
引导时自动装载:编辑/boot/loader.conf
zfs_load="YES"
6. 引导消息解读(关键线索)
6.1 Linux引导消息关键点
| 消息模式 | 含义 |
|---|---|
Linux version ... |
内核版本、编译器、构建者 |
Command line: ... |
内核启动参数(从GRUB传入) |
BIOS-provided physical RAM map |
物理内存映射 |
Hypervisor detected: KVM |
虚拟化环境检测 |
ACPI: ... |
电源管理和设备枚举 |
SCSI subsystem initialized |
SCSI子系统 |
e1000: Intel PRO/1000 |
网卡识别(含MAC地址) |
ata3: SATA link up |
SATA/磁盘识别 |
XFS (dm-0): Mounting |
文件系统挂载 |
Loading compiled-in X.509 certificates |
内核签名验证 |
💡 引导消息可通过
dmesg或journalctl -k查看。虚拟化环境中,内核会报告hypervisor类型。
6.2 FreeBSD引导消息关键点
| 消息模式 | 含义 |
|---|---|
FreeBSD X.Y-RELEASE |
系统版本 |
real memory = X MB |
物理内存总量 |
avail memory = X MB |
可用内存(用户空间) |
em0: Ethernet address: xx:xx:xx |
网卡MAC |
ada0: <VBOX HARDDISK> |
磁盘识别(SATA/ATA) |
Trying to mount root from ufs://... |
根文件系统挂载 |
FreeBSD引导消息比Linux简洁得多,更易于快速扫描。
7. 内核错误(Kernel Panic / Oops)
7.1 故障类型对比
| 类型 | 说明 | 常见原因 |
|---|---|---|
| 软死锁(Soft Lockup) | 内核模式运行超时,中断仍可处理 | 内存损坏、非标准模块 |
| 硬死锁(Hard Lockup) | 中断也无法处理,系统完全挂起 | 硬件故障 |
| 内核恐慌(Panic) | 内核检测到不可恢复错误,挂起系统 | 硬件故障、驱动程序bug |
| Oops(Linux) | 较轻错误,可能恢复(不总是恐慌) | 内存访问错误 |
7.2 Linux死锁 → 自动恐慌
7.3 查看崩溃信息
物理/虚拟控制台:提高分辨率显示完整转储
- GRUB引导参数添加
vga=795(1280×1024) - 表11.6列出了常用分辨率对应的VGA模式值
FreeBSD崩溃转储:
- 启用内核调试:
makeoptions DEBUG=-g - 崩溃转储位置:
/var/crash/ - 使用
kgdb分析 - 转储文件大小=物理内存大小,确保
/var/crash有足够空间 - 配置:
/etc/rc.conf中的dumpdev变量
8. 云环境中的内核引导
| 平台 | 内核引导机制 |
|---|---|
| AWS | 从PV-GRUB AMI开始,修改/boot/grub/menu.lst指定内核,建议保留备用内核 |
| DigitalOcean | 现代OS支持使用自己的引导装载程序(GRUB) |
| GCP | 必须使用MBR分区(非UEFI/GPT),上传完整磁盘镜像 |
AWS GRUB menu.lst示例:
default 0
fallback 1
timeout 0
title My Linux Kernel
kernel /boot/my-vmlinux-4.3 root=LABEL=/ console=hvc0
initrd /boot/my-initrd.img-4.3
title Amazon Linux (fallback)
kernel /boot/vmlinux-4.1.10-17.31.amzn1.x86 root=LABEL=/ console=hvc0
initrd /boot/initramfs-4.1.10-17.31.amzn1.x86.img
9. 本章核心命令速查表
| 命令 | 功能 | 平台 |
|---|---|---|
uname -r |
查看内核版本 | 全平台 |
lsmod |
列出已装载模块 | Linux |
modprobe module |
装载模块(含依赖) | Linux |
modprobe -r module |
卸载模块 | Linux |
lsusb |
列出USB设备 | Linux |
udevadm info -a -n /dev/sdb |
查询设备属性 | Linux |
udevadm control --reload-rules |
重新载入udev规则 | Linux |
sysctl -a |
列出所有可调参数 | Linux/FreeBSD |
sysctl -p |
加载/etc/sysctl.conf | Linux |
kldstat / kldload / kldunload |
模块管理 | FreeBSD |
dmesg |
查看内核引导消息 | 全平台 |
journalctl -k |
查看内核日志(systemd) | Linux |
make menuconfig |
内核配置(菜单界面) | Linux |
make buildkernel KERNCONF=... |
构建内核 | FreeBSD |
lspci |
列出PCI设备 | Linux/FreeBSD |
DBA视角补充:
- 共享内存调优(
kernel.shmmax/kernel.shmall):Oracle、PostgreSQL等数据库依赖共享内存,安装前务必按官方文档调整。不正确的设置会导致数据库无法启动。- 文件描述符限制(
fs.file-max/kern.maxfiles):高并发数据库连接数大,需同时调整内核参数和进程限制(/etc/security/limits.conf)。- 网络参数(
net.ipv4.ip_local_port_range/tcp_fin_timeout):应用服务器连接数据库频繁,调大端口范围+降低FIN超时可减少端口耗尽风险。- 内核恐慌排查:数据库服务器若出现kernel panic,优先检查内存硬件(ECC错误)、磁盘控制器、非标准驱动(如厂商提供的RAID驱动)。使用
dmesg或journalctl -k查看死锁前的最后消息。- 多版本内核保留:生产数据库服务器升级内核后,务必保留旧内核作为GRUB备用选项,万一新内核无法引导可快速回退。
- 云数据库注意事项:AWS EC2实例使用PV-GRUB时,若编译自定义内核需确保
xen-blkfront等虚拟化驱动已包含,否则实例无法识别根磁盘。
文章作者 会写代码的小郎中
上次更新 2011-06-21
许可协议 CC BY-NC-ND 4.0