1. Linux内核的核心功能与架构
1.1 内核的核心作用
- 资源管理:协调CPU、内存、磁盘、网络等硬件资源。
- 进程调度:决定进程的运行顺序和时间片分配。
- 文件系统:管理磁盘数据的组织和访问。
- 设备驱动:提供硬件设备的统一操作接口。
1.2 内核架构概览
2. 进程管理:从fork到调度器
2.1 进程生命周期
关键系统调用
- fork():创建新进程,复制父进程地址空间。
- execve():加载新程序到当前进程。
- wait():父进程等待子进程退出。
示例:进程创建
#include
#include
int main() {
pid_t pid = fork();
if (pid == 0) {
printf("子进程PID: %d\n", getpid());
} else {
printf("父进程PID: %d\n", getpid());
}
return 0;
}
2.2 进程调度器
调度策略
策略 | 描述 | 适用场景 |
CFS | 完全公平调度,基于虚拟时间分配CPU | 通用场景(默认策略) |
实时调度 | SCHED_FIFO/SCHED_RR,优先级抢占 | 实时任务(如音视频) |
调整进程优先级
# 启动进程并设置nice值(-20最高,19最低)
nice -n -10 ./cpu_intensive_task
# 实时进程优先级设置(1-99,99最高)
chrt -r 99 ./realtime_task
3. 内存管理:从物理内存到虚拟地址
3.1 虚拟内存机制
地址空间划分
- 用户空间:0x00000000 到 0xBFFFFFFF(3GB)。
- 内核空间:0xC0000000 到 0xFFFFFFFF(1GB)。
页表与TLB
- 页表:记录虚拟地址到物理地址的映射。
- TLB:缓存常用页表项,加速地址转换。
3.2 内存分配器
伙伴系统(Buddy System)
- 管理物理内存:以页(通常4KB)为单位分配。
- 解决外部碎片:通过合并空闲块减少碎片。
Slab分配器
- 优化小对象分配:如进程描述符(task_struct)、文件对象(file)。
查看内存使用
# 查看进程内存映射
pmap -x
# 分析内存碎片
cat /proc/buddyinfo
4. 文件系统:从VFS到Ext4/XFS
4.1 虚拟文件系统(VFS)
核心对象
- 超级块(Superblock):文件系统元数据(如块大小、inode数)。
- Inode:文件元数据(权限、大小、数据块指针)。
- Dentry:目录项缓存,加速路径查找。
文件系统挂载流程
4.2 Ext4与XFS对比
特性 | Ext4 | XFS |
最大文件 | 16TB | 8EB |
日志模式 | 有序日志(默认) | 元数据日志 |
碎片处理 | 离线e4defrag | 在线碎片整理 |
适用场景 | 通用服务器 | 大文件、高并发写入 |
优化Ext4性能
# 格式化时启用大文件支持
mkfs.ext4 -T largefile /dev/sdb1
# 挂载选项优化
mount -o noatime,nodiratime,data=writeback /dev/sdb1 /data
5. 设备驱动:从字符设备到内核模块
5.1 设备类型
- 字符设备:按字节流访问(如键盘、串口)。
- 块设备:按数据块访问(如磁盘、SSD)。
- 网络设备:基于数据包通信(如网卡)。
5.2 编写简单字符设备驱动
代码示例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#define DEVICE_NAME "mydev"
static int major;
static int mydev_open(struct inode *inode, struct file *file) {
printk(KERN_INFO "设备已打开\n");
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = mydev_open,
};
static int __init mydev_init(void) {
major = register_chrdev(0, DEVICE_NAME, &fops);
printk(KERN_INFO "设备注册成功,主设备号: %d\n", major);
return 0;
}
static void __exit mydev_exit(void) {
unregister_chrdev(major, DEVICE_NAME);
printk(KERN_INFO "设备已卸载\n");
}
module_init(mydev_init);
module_exit(mydev_exit);
MODULE_LICENSE("GPL");
编译与加载
# 编译内核模块
make -C /lib/modules/$(uname -r)/build M=$PWD modules
# 加载模块
insmod mydev.ko
# 查看设备号
cat /proc/devices | grep mydev
# 创建设备文件
mknod /dev/mydev c 0
6. 生产案例:内核参数调优与故障排查
6.1 网络性能调优
关键参数
# 增加TCP连接队列
sysctl -w net.core.somaxconn=4096
# 加快TIME-WAIT回收
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=30
# 优化本地端口范围
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
6.2 内存泄漏排查
工具组合
- vmstat:观察内存使用趋势。
- slabtop:分析内核对象占用。
- kmemleak:检测未释放的内存块。
启用kmemleak
# 启动时启用kmemleak
echo 1 > /sys/kernel/debug/kmemleak/vmalloc
# 扫描并报告泄漏
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
7. 总结:深入内核,掌握Linux的灵魂
Linux内核是系统运行的基石,理解其核心机制能帮助运维工程师:
- 精准定位性能瓶颈(如调度延迟、内存泄漏)。
- 优化系统配置(如文件系统参数、网络栈调优)。
- 编写定制化工具(如内核模块、性能监控脚本)。