Linux启动过程详解
以下是Linux启动过程的详细树状图,从硬件上电开始,展示了内核初始化、设备驱动加载、用户空间启动以及应用程序与系统交互的完整流程。图中包含了关键函数调用、数据结构初始化和进程创建链。
[硬件上电]
└───> [BIOS/UEFI初始化]
├─── POST自检
│ ├─── 检测CPU、内存、显卡、硬盘等硬件
│ ├─── 初始化基本输入输出系统
│ └─── 确定启动设备顺序
│
└─── 引导加载程序(GRUB)
├─── 从MBR/GPT读取引导代码
├─── 加载GRUB核心模块
│ ├─── 解析grub.cfg配置文件
│ ├─── 显示启动菜单
│ └─── 支持参数调整(如single模式)
│
└─── 加载内核和initrd
├─── 读取/boot/vmlinuz (压缩内核映像)
├─── 读取/boot/initrd (初始RAM磁盘)
└─── 传递启动参数(如root=、ro、console=)
│
└───> [内核启动 - arch/x86/boot]
├─── _start() [entry.S]
│ ├─── 实模式初始化(16位)
│ │ ├─── 设置堆栈指针
│ │ ├─── 初始化段寄存器
│ │ └─── 检测A20地址线
│ │
│ ├─── 切换到保护模式(32位)
│ │ ├─── 加载GDT(全局描述符表)
│ │ ├─── 设置CR0寄存器
│ │ └─── 长跳转刷新CS寄存器
│ │
│ └─── 初始化保护模式环境
│ ├─── 设置临时页表
│ ├─── 加载IDT(中断描述符表)
│ └─── 跳转到start_kernel()
│
└─── start_kernel() [init/main.c]
├─── setup_arch() [架构相关初始化]
│ ├─── 解析启动参数
│ ├─── 初始化内存映射
│ ├─── 检测CPU特性
│ └─── 设置TLB和缓存
│
├─── setup_per_cpu_areas() [初始化CPU局部存储]
│
├─── mm_init() [内存管理初始化]
│ ├─── memblock_init() [初始化内存块管理]
│ ├─── setup_bootmem() [初始化引导内存分配器]
│ ├─── page_alloc_init() [初始化页分配器]
│ └─── slab_init() [初始化SLAB分配器]
│
├─── sched_init() [调度器初始化]
│ ├─── 初始化调度类
│ ├─── 创建idle进程
│ ├─── 初始化运行队列
│ └─── 设置调度策略
│
├─── trap_init() [异常和中断初始化]
│ ├─── 设置IDT表项
│ ├─── 注册异常处理函数
│ └─── 初始化系统调用表
│
├─── init_IRQ() [中断控制器初始化]
│ ├─── 配置中断控制器(如IOAPIC)
│ ├─── 注册中断处理函数
│ └─── 初始化中断向量
│
├─── time_init() [时钟初始化]
│ ├─── 初始化系统时钟
│ ├─── 设置定时器中断
│ └─── 初始化jiffies
│
├─── console_init() [控制台初始化]
│ ├─── 注册控制台驱动
│ └─── 初始化打印函数
│
├─── vfs_caches_init() [虚拟文件系统缓存初始化]
│ ├─── 初始化dentry缓存
│ └─── 初始化inode缓存
│
└─── rest_init() [剩余初始化]
├─── 创建内核线程
│ ├─── kernel_init() [PID 1]
│ ├─── ksoftirqd() [软中断处理]
│ ├─── kworker() [工作队列处理]
│ ├─── migration() [进程迁移]
│ └─── watchdog() [看门狗定时器]
│
└───> [内核驱动初始化]
├─── drivers_init()
│ ├─── 初始化驱动核心框架
│ ├─── 注册总线类型
│ │ ├─── platform总线
│ │ ├─── PCI总线
│ │ ├─── USB总线
│ │ ├─── I2C总线
│ │ └─── SPI总线
│ │
│ └─── 初始化子系统
│ ├─── 块设备子系统
│ ├─── 字符设备子系统
│ ├─── 网络子系统
│ ├─── 输入子系统
│ └─── 电源管理子系统
│
├─── 总线扫描与驱动匹配
│ ├─── PCI总线扫描
│ │ ├─── pci_early_init() [早期PCI初始化]
│ │ ├─── pci_subsys_init() [PCI子系统初始化]
│ │ ├─── pci_scan_bus() [扫描PCI总线]
│ │ ├─── pci_device_probe() [探测PCI设备]
│ │ └─── pci_register_driver() [注册PCI驱动]
│ │
│ ├─── USB总线扫描
│ │ ├─── usb_init() [USB子系统初始化]
│ │ ├─── usb_hub_init() [USB集线器初始化]
│ │ ├─── usb_register_device_driver() [注册USB设备驱动]
│ │ └─── hub_probe() [探测USB集线器]
│ │
│ └─── 其他总线扫描
│
├─── 驱动加载与初始化
│ ├─── 内置驱动初始化
│ │ ├─── 调用驱动的init函数
│ │ ├─── 注册设备操作方法
│ │ └─── 创建设备结构
│ │
│ ├─── 模块驱动加载
│ │ ├─── request_module() [请求加载模块]
│ │ ├─── load_module() [加载模块]
│ │ ├─── module_init() [模块初始化]
│ │ └─── init_module() [初始化函数入口]
│ │
│ └─── 驱动注册示例
│ ├─── 字符设备驱动注册
│ │ ├─── alloc_chrdev_region() [分配设备号]
│ │ ├─── cdev_init() [初始化字符设备]
│ │ ├─── cdev_add() [添加字符设备]
│ │ └─── class_create() [创建设备类]
│ │
│ ├─── 块设备驱动注册
│ │ ├─── register_blkdev() [注册块设备]
│ │ ├─── alloc_disk() [分配磁盘结构]
│ │ ├─── set_disk_operations() [设置磁盘操作]
│ │ └─── add_disk() [添加磁盘]
│ │
│ └─── 网络设备驱动注册
│ ├─── alloc_netdev() [分配网络设备]
│ ├─── ether_setup() [以太网设备设置]
│ ├─── register_netdev() [注册网络设备]
│ └─── netdev_init() [网络设备初始化]
│
└─── 设备节点创建
├─── class_create() [创建设备类]
├─── device_create() [创建设备实例]
└─── 在/dev目录下创建设备文件
├─── 字符设备文件(如/dev/ttyS0)
├─── 块设备文件(如/dev/sda)
├─── 网络设备文件(如/dev/net/tun)
└─── 其他设备文件(如/dev/input/event0)
│
└───> [initramfs处理]
├─── 挂载initramfs
├─── 执行早期脚本
│ ├─── 加载必要驱动
│ ├─── 初始化存储设备
│ └─── 准备根文件系统
│
└─── 切换到真正的根文件系统
│
└───> [kernel_init() 继续]
├─── 启动用户空间init进程
│ ├─── 执行/sbin/init (systemd)
│ │ ├─── 解析配置文件
│ │ ├─── 启动基本服务
│ │ └─── 进入默认target
│ │
│ └───> [systemd 启动流程]
│ ├─── 启动sysinit.target
│ │ ├─── systemd-udevd [设备管理]
│ │ │ ├─── 监听内核uevent事件
│ │ │ ├─── 根据规则创建设备节点
│ │ │ └─── 配置设备属性
│ │ │
│ │ ├─── systemd-journald [日志服务]
│ │ ├─── systemd-hwdb [硬件数据库]
│ │ └─── systemd-sysctl [系统参数设置]
│ │
│ ├─── 启动basic.target
│ │ ├─── systemd-logind [登录管理]
│ │ ├─── systemd-user-sessions [用户会话]
│ │ ├─── systemd-timesyncd [时间同步]
│ │ └─── systemd-resolved [DNS解析]
│ │
│ └─── 启动default.target (graphical.target)
│ ├─── systemd-display-manager [显示管理器]
│ │ ├─── gdm.service [GNOME显示管理器]
│ │ ├─── lightdm.service [轻量级显示管理器]
│ │ └─── 创建Xorg/Wayland会话
│ │
│ └─── 用户登录
│ ├─── 启动桌面环境
│ │ ├─── GNOME
│ │ ├─── KDE
│ │ └─── Xfce等
│ │
│ └─── 执行用户应用程序
│ ├─── shell (bash/zsh)
│ ├─── 图形应用
│ └─── 系统服务
│ ├─── NetworkManager
│ ├─── cron
│ └─── sshd等
│ │
│ └───> [应用程序与系统交互]
│ ├─── 系统调用
│ │ ├─── 通过int 0x80或syscall指令触发
│ │ ├─── 进入内核态执行服务例程
│ │ └─── 返回用户态
│ │
│ ├─── 常见系统调用分类
│ │ ├─── 文件操作(open, read, write, close)
│ │ ├─── 进程控制(fork, exec, wait)
│ │ ├─── 信号处理(kill, signal)
│ │ ├─── 内存管理(brk, mmap)
│ │ └─── 网络通信(socket, bind, connect)
│ │
│ ├─── 内核服务
│ │ ├─── 文件系统
│ │ │ ├─── VFS(虚拟文件系统)
│ │ │ ├─── 具体文件系统(ext4, xfs)
│ │ │ └─── 文件缓存机制
│ │ │
│ │ ├─── 进程管理
│ │ │ ├─── 进程调度
│ │ │ ├─── 进程间通信(IPC)
│ │ │ └─── 信号机制
│ │ │
│ │ ├─── 内存管理
│ │ │ ├─── 虚拟内存
│ │ │ ├─── 物理内存分配
│ │ │ └─── 页面置换算法
│ │ │
│ │ └─── 网络协议栈
│ │ ├─── 链路层(以太网, WiFi)
│ │ ├─── 网络层(IP, ICMP)
│ │ ├─── 传输层(TCP, UDP)
│ │ └─── 应用层(HTTP, FTP)
│ │
│ ├─── 设备驱动交互
│ │ ├─── 通过/dev/ 目录下的设备文件访问
│ │ ├─── 文件操作映射到驱动函数
│ │ │ ├─── open() → 驱动的open方法
│ │ │ ├─── read() → 驱动的read方法
│ │ │ └─── ioctl() → 驱动的ioctl方法
│ │ │
│ │ └─── 中断处理机制
│ │ ├─── 硬件触发中断
│ │ ├─── 内核中断处理程序
│ │ └─── 驱动的中断回调
│ │
│ └─── 硬件操作
│ ├─── 内存映射IO(MMIO)
│ ├─── 端口IO
│ ├─── DMA操作
│ └─── 中断控制
Linux 系统启动后的整体框架树状图
[Linux系统整体框架]
├─── [内核空间 (Kernel Space)]
│ ├─── 核心子系统
│ │ ├─── 进程调度子系统
│ │ │ ├─── 进程/线程管理
│ │ │ │ ├─── struct task_struct (进程描述符)
│ │ │ │ ├─── 进程状态管理
│ │ │ │ ├─── 进程上下文切换
│ │ │ │ └─── 进程优先级调度
│ │ │ │
│ │ │ ├─── 调度算法
│ │ │ │ ├─── CFS (完全公平调度器)
│ │ │ │ ├─── RT (实时调度器)
│ │ │ │ └─── IDLE (空闲调度器)
│ │ │ │
│ │ │ └─── 进程间通信(IPC)
│ │ │ ├─── 信号(Signal)
│ │ │ ├─── 管道(Pipe)
│ │ │ ├─── 消息队列(Message Queue)
│ │ │ ├─── 共享内存(Shared Memory)
│ │ │ └─── 套接字(Socket)
│ │ │
│ │ ├─── 内存管理子系统
│ │ │ ├─── 虚拟内存管理
│ │ │ │ ├─── 页表机制
│ │ │ │ ├─── 虚拟地址空间管理
│ │ │ │ └─── 页面置换算法(如LRU)
│ │ │ │
│ │ │ ├─── 物理内存管理
│ │ │ │ ├─── 内存区域(Zone)划分
│ │ │ │ ├─── 伙伴系统(Buddy System)
│ │ │ │ └─── SLAB/SLOB/SLUB分配器
│ │ │ │
│ │ │ └─── 内存映射
│ │ │ ├─── 文件映射
│ │ │ ├─── 匿名映射
│ │ │ └─── 设备内存映射
│ │ │
│ │ ├─── 文件系统子系统
│ │ │ ├─── VFS (虚拟文件系统)
│ │ │ │ ├─── struct inode (索引节点)
│ │ │ │ ├─── struct dentry (目录项)
│ │ │ │ ├─── struct file (文件对象)
│ │ │ │ └─── struct super_block (超级块)
│ │ │ │
│ │ │ ├─── 具体文件系统实现
│ │ │ │ ├─── ext4
│ │ │ │ ├─── xfs
│ │ │ │ ├─── btrfs
│ │ │ │ ├─── tmpfs
│ │ │ │ └─── NFS (网络文件系统)
│ │ │ │
│ │ │ └─── 文件缓存机制
│ │ │ ├─── 页缓存(Page Cache)
│ │ │ ├─── dentry缓存
│ │ │ └─── inode缓存
│ │ │
│ │ ├─── 网络协议栈
│ │ │ ├─── 链路层
│ │ │ │ ├─── 以太网驱动
│ │ │ │ ├─── WiFi驱动
│ │ │ │ └─── 帧处理
│ │ │ │
│ │ │ ├─── 网络层
│ │ │ │ ├─── IP协议
│ │ │ │ ├─── ICMP协议
│ │ │ │ ├─── 路由选择
│ │ │ │ └─── IP转发
│ │ │ │
│ │ │ ├─── 传输层
│ │ │ │ ├─── TCP协议
│ │ │ │ ├─── UDP协议
│ │ │ │ └─── 套接字API
│ │ │ │
│ │ │ └─── 应用层
│ │ │ ├─── HTTP协议
│ │ │ ├─── FTP协议
│ │ │ ├─── DNS协议
│ │ │ └─── 其他网络服务
│ │ │
│ │ └─── 设备驱动框架
│ │ ├─── 总线驱动
│ │ │ ├─── PCI总线
│ │ │ ├─── USB总线
│ │ │ ├─── I2C总线
│ │ │ └─── SPI总线
│ │ │
│ │ ├─── 设备类型驱动
│ │ │ ├─── 字符设备驱动
│ │ │ │ ├─── 串口驱动
│ │ │ │ ├─── 键盘驱动
│ │ │ │ └─── 鼠标驱动
│ │ │ │
│ │ │ ├─── 块设备驱动
│ │ │ │ ├─── 硬盘驱动
│ │ │ │ ├─── SSD驱动
│ │ │ │ └─── 光驱驱动
│ │ │ │
│ │ │ └─── 网络设备驱动
│ │ │ ├─── 网卡驱动
│ │ │ ├─── 无线网卡驱动
│ │ │ └─── 网络协议驱动
│ │ │
│ │ └─── 驱动管理机制
│ │ ├─── 驱动注册/注销
│ │ ├─── 设备探测
│ │ ├─── 驱动与设备匹配
│ │ └─── 设备文件创建
│ │
│ ├─── 系统调用接口
│ │ ├─── 系统调用表
│ │ ├─── 系统调用处理程序
│ │ └─── 用户空间访问方法
│ │ ├─── int 0x80 (32位)
│ │ ├─── syscall (64位)
│ │ └─── vDSO (虚拟动态共享对象)
│ │
│ └─── 中断与异常处理
│ ├─── IDT (中断描述符表)
│ ├─── 硬件中断处理
│ ├─── 软件异常处理
│ └─── 中断优先级管理
│
├─── [用户空间 (User Space)]
│ ├─── 系统服务
│ │ ├─── 初始化系统
│ │ │ ├─── systemd (PID 1)
│ │ │ ├─── 服务管理
│ │ │ ├─── 目标(target)管理
│ │ │ └─── 系统状态监控
│ │ │
│ │ ├─── 设备管理
│ │ │ ├─── udev (设备管理器)
│ │ │ ├─── 动态设备识别
│ │ │ └─── 设备节点创建
│ │ │
│ │ ├─── 日志管理
│ │ │ ├─── systemd-journald
│ │ │ ├─── rsyslog
│ │ │ └─── 日志存储与查询
│ │ │
│ │ ├─── 网络服务
│ │ │ ├─── NetworkManager
│ │ │ ├─── dhcpcd
│ │ │ ├─── sshd
│ │ │ └─── httpd (如Apache/Nginx)
│ │ │
│ │ ├─── 图形服务
│ │ │ ├─── Xorg/X11
│ │ │ ├─── Wayland
│ │ │ └─── 显示管理器(gdm/lightdm)
│ │ │
│ │ └─── 其他系统服务
│ │ ├─── cron (任务调度)
│ │ ├─── dbus (进程间通信总线)
│ │ ├─── avahi (零配置网络)
│ │ └─── cups (打印系统)
│ │
│ ├─── 应用环境
│ │ ├─── shell环境
│ │ │ ├─── bash
│ │ │ ├─── zsh
│ │ │ ├─── fish
│ │ │ └─── 命令行工具
│ │ │
│ │ ├─── 图形环境
│ │ │ ├─── 桌面环境
│ │ │ │ ├─── GNOME
│ │ │ │ ├─── KDE Plasma
│ │ │ │ ├─── Xfce
│ │ │ │ └─── LXDE
│ │ │ │
│ │ │ └─── 窗口管理器
│ │ │ ├─── i3
│ │ │ ├─── awesome
│ │ │ └─── Openbox
│ │ │
│ │ └─── 开发环境
│ │ ├─── 编译器(gcc, clang)
│ │ ├─── 解释器(Python, Ruby)
│ │ ├─── 构建工具(make, cmake)
│ │ └─── 版本控制(git)
│ │
│ └─── 库函数
│ ├─── C库
│ │ ├─── glibc (GNU C Library)
│ │ ├─── musl libc
│ │ └─── 系统调用封装
│ │
│ ├─── 图形库
│ │ ├─── GTK
│ │ ├─── Qt
│ │ ├─── OpenGL
│ │ └─── Vulkan
│ │
│ ├─── 网络库
│ │ ├─── libcurl
│ │ ├─── openssl
│ │ └─── libpcap
│ │
│ └─── 其他库
│ ├─── libxml2
│ ├─── sqlite3
│ ├─── ffmpeg
│ └─── SDL (多媒体)
│
└─── [交互机制]
├─── 系统调用
│ ├─── 用户空间 → 内核空间
│ ├─── 提供特权操作接口
│ └─── 通过统一API访问内核服务
│
├─── 进程间通信(IPC)
│ ├─── 管道(Pipe)
│ ├─── 消息队列(Message Queue)
│ ├─── 共享内存(Shared Memory)
│ └─── 套接字(Socket)
│
├─── 设备文件
│ ├─── /dev/ 目录下的设备节点
│ ├─── 字符设备文件(如/dev/ttyS0)
│ ├─── 块设备文件(如/dev/sda)
│ └─── 通过文件操作访问硬件
│
└─── 信号机制
├─── 进程间异步通信
├─── 常用信号(SIGINT, SIGTERM, SIGKILL)
└─── 信号处理函数注册
关键数据结构与调用关系
内核关键数据结构
struct task_struct
:进程描述符,包含进程状态、优先级、内存信息等struct mm_struct
:内存管理结构,管理进程的虚拟地址空间struct file
:文件对象,表示打开的文件struct inode
:索引节点,存储文件元数据struct dentry
:目录项,实现文件路径查找struct device
:设备结构,表示系统中的物理或虚拟设备struct device_driver
:设备驱动,实现设备的操作方法
关键调用关系
request_module()
:动态加载内核模块register_chrdev()
:注册字符设备驱动register_blkdev()
:注册块设备驱动class_create()
:创建设备类device_create()
:创建设备节点sysfs_create_file()
:在sysfs中创建设备属性文件
1. 硬件上电与BIOS/UEFI阶段
1.1 硬件初始化
- 电源开启:按下电源按钮后,电源供应单元(PSU)开始向主板和其他组件供电。
- 硬件自检(POST):BIOS/UEFI固件执行加电自检,检测基本硬件(CPU、内存、硬盘、显卡等)。
- BIOS/UEFI初始化:初始化系统设备,设置中断向量表,读取CMOS/UEFI配置。
1.2 引导加载程序(Bootloader)加载
- MBR/GPT检测:BIOS/UEFI从启动设备(通常是硬盘)读取主引导记录(MBR)或GPT分区表。
- Bootloader加载:MBR中的引导代码加载GRUB/LILO等引导加载程序。
- GRUB菜单:显示可用内核选项,允许用户选择启动参数(如单用户模式、安全模式)。
2. 内核加载与初始化
2.1 内核加载
- 内核映像加载:GRUB从/boot分区加载内核映像(vmlinuz)和初始RAM磁盘(initrd/initramfs)。
- 控制权移交:BIOS/UEFI将控制权交给Linux内核。
2.2 内核初始化
- 早期初始化:内核解压并初始化内存管理、CPU调度等核心子系统。
- 设备检测:扫描并识别硬件设备,加载必要的驱动程序。
- 内存初始化:设置页表,初始化物理内存管理。
- 中断系统设置:配置中断控制器和中断处理程序。
2.3 驱动程序加载
- 内置驱动:加载编译进内核的驱动程序。
- 模块化驱动:通过initrd/initramfs加载必要的模块(如存储控制器驱动)。
- 根文件系统挂载:挂载根文件系统(通常是ext4、XFS等)。
3. 用户空间初始化
3.1 initramfs/initrd处理
- 临时根文件系统:initramfs提供临时根文件系统,包含早期启动所需的工具和驱动。
- 根文件系统准备:挂载真正的根文件系统,执行必要的文件系统检查。
3.2 init进程启动
- PID 1:内核启动第一个用户空间进程
init
(或systemd、upstart)。 - 运行级别设置:传统SysVinit根据
/etc/inittab
确定运行级别(0-6),现代系统使用targets替代。
3.3 系统服务启动
- SysVinit:按顺序执行
/etc/rc.d/rc*.d
目录下的脚本。 - systemd:并行启动独立单元(unit),通过依赖关系管理服务顺序。
- 关键服务:启动网络、日志、用户认证等基础服务。
4. 登录与用户会话
4.1 登录服务启动
- getty进程:启动终端登录服务(如tty1-tty6)。
- 图形界面:启动显示管理器(如GDM、LightDM),加载桌面环境(如GNOME、KDE)。
4.2 用户会话创建
- 用户认证:验证用户身份,创建shell会话。
- 环境设置:加载用户配置文件(
.bashrc
、.profile
等)。
5. 应用程序与系统交互
5.1 系统调用
- 用户态→内核态:应用通过系统调用(如
open()
、read()
)请求内核服务。 - 上下文切换:CPU从用户模式切换到内核模式执行特权操作。
5.2 设备驱动交互
- 设备文件:应用通过
/dev/
目录下的设备文件访问硬件(如/dev/sda
、/dev/ttyS0
)。 - 驱动接口:内核驱动提供统一的文件操作接口(read/write/ioctl)。
5.3 进程管理
- fork/exec:应用通过
fork()
创建子进程,通过exec()
加载新程序。 - 信号处理:进程间通过信号(如SIGTERM、SIGKILL)进行通信。
6. 系统启动后的整体框架
6.1 内核空间
- 核心子系统:内存管理、进程调度、文件系统、网络协议栈、设备驱动。
- 系统调用接口:提供用户空间访问内核功能的统一接口。
6.2 用户空间
- 系统服务:systemd、dbus、NetworkManager等守护进程。
- 应用环境:shell、图形界面、开发工具链、用户应用程序。
- 库函数:C库(glibc)、图形库(GTK、Qt)等提供应用编程接口。
7. 关键函数与程序加载过程
7.1 内核启动关键函数
start_kernel()
:内核入口点,初始化核心子系统。setup_arch()
:初始化硬件架构相关设置。mm_init()
:初始化内存管理系统。sched_init()
:初始化进程调度器。console_init()
:初始化控制台。rest_init()
:启动内核线程,最终调用kernel_init()
。
7.2 initramfs关键步骤
init
脚本执行:挂载根文件系统前的准备工作。- 模块加载:通过
modprobe
加载必要的驱动模块。 - 根文件系统挂载:将真正的根文件系统从磁盘/网络挂载。
7.3 systemd启动流程
systemd
初始化:解析配置文件,启动基本.target。- 依赖关系解析:分析并启动所有依赖的服务单元。
- 并行启动:无依赖关系的服务并行启动。
- 默认target激活:通常是graphical.target或multi-user.target。
8. 总结
Linux启动过程是一个从硬件到软件、从内核到用户空间的多层次初始化过程。理解这一过程有助于系统故障排查、性能优化和定制化配置。现代Linux发行版(如Ubuntu、Fedora)主要采用systemd作为初始化系统,相比传统SysVinit提供了更快的启动速度和更灵活的服务管理。
总结
这个树状图清晰展示了Linux系统从硬件上电到用户应用程序运行的完整启动过程,包括:
- 硬件初始化:BIOS/UEFI执行POST自检,加载引导程序
- 内核启动:从实模式到保护模式,初始化核心子系统
- 设备驱动加载:注册各类设备驱动,识别硬件
- 用户空间初始化:systemd启动各种系统服务和显示管理器
- 用户会话与应用程序:用户登录后运行shell和应用程序
- 系统交互:应用程序通过系统调用与内核和硬件通信
理解这个流程对于系统管理员和开发者非常重要,例如:
- 系统故障排查:可以根据启动流程定位问题出现的阶段
- 性能优化:了解各组件启动顺序,优化关键服务的启动时间
- 内核开发:掌握驱动注册和初始化的时机与方式