《UNIX/Linux系统管理技术手册-读书笔记-第十一章

驱动程序与内核

1. 内核概述

1.1 内核职责

功能 说明
硬件管理 通过驱动程序抽象硬件细节
进程/线程管理 CPU分时、调度、进程间通信
内存管理 虚拟内存、地址空间、内存保护
I/O设施 文件系统、网络接口、串口等
杂务(Housekeeping) 启动、关机、定时器、多任务

核心理念:内核为硬件提供抽象接口,用户进程通过系统调用与内核交互,无需关心底层硬件细节。

1.2 内核版本

Linux内核版本

  • 语义化版本:主版本.次版本.补丁号
  • 次版本号与稳定性无固定关系(旧规则已废弃)
  • 发行版通常使用较旧但经过充分测试的内核版本
  • 不建议手动将新内核硬装到现有发行版,应选择针对该内核设计的发行版

FreeBSD内核版本

  • 与操作系统统一版本号
  • 两个主版本同时维护(如10.x稳定维护,11.x活跃开发)
  • 大版本支持5年,小版本支持至下个大版本发布后3个月
1
uname -r   # 查看当前内核版本

2. 设备与驱动程序

2.1 设备文件与设备编号

概念 说明
设备文件 /dev下的特殊文件,用户空间访问驱动程序的入口
主设备号(Major) 标识设备类型/驱动程序
次设备号(Minor) 标识设备实例或特定功能
块设备(b) 按块读写(磁盘)
字符设备(c) 按字节读写(终端、串口)
伪设备 无实际硬件,如/dev/null/dev/zero/dev/urandom、PTY

查看设备号

1
2
3
ls -l /dev/sda
# brw-rw---- 1 root disk 8, 0 Jul 13 01:38 /dev/sda
# 主设备号=8,次设备号=0

网络接口在/dev无设备文件,使用独立的命名系统(如eth0enp0s3)。

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 底层卸载

模块参数传递

1
modprobe snd-usb-audio nrpacks=8 async_unlink=1

配置文件/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 内核签名验证

💡 引导消息可通过dmesgjournalctl -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死锁 → 自动恐慌

1
2
3
4
# 软死锁时自动panic并重启
sysctl kernel.softlockup_panic=1
sysctl kernel.nmi_watchdog=1
# 永久配置放入 /etc/sysctl.conf

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驱动)。使用dmesgjournalctl -k查看死锁前的最后消息。
  • 多版本内核保留:生产数据库服务器升级内核后,务必保留旧内核作为GRUB备用选项,万一新内核无法引导可快速回退。
  • 云数据库注意事项:AWS EC2实例使用PV-GRUB时,若编译自定义内核需确保xen-blkfront等虚拟化驱动已包含,否则实例无法识别根磁盘。