Linux 驱动
内核(kernel) 是操作系统的大脑核心驱动(Driver)是内核中负责“跟某一块硬件说话”的那部分代码。一. 分层架构二. 内核和驱动对比对比维度内核Kernel驱动Driver定义操作系统核心管理所有资源内核中负责控制某个具体硬件的模块代码量占比整体 100%约占内核代码的 45%~70%职责调度、内存、文件系统、网络、安全初始化硬件、处理中断、暴露接口给上层运行级别EL1内核态EL1同样运行在内核态加载时机启动时 start_kernel ()do_initcalls () 阶段即 module_init ()存在形式vmlinux编译固化可编译进内核也可以是 .ko 模块动态加载能否单独存在✅ 内核可以没有某个驱动运行❌ 驱动必须运行在内核环境中三. 驱动在内核中的位置linux/ ├── kernel/ ← 内核核心调度器、时钟、信号 ├── mm/ ← 内存管理buddy、slab、vmalloc ├── fs/ ← 文件系统ext4、VFS ├── net/ ← 网络协议栈 ├── arch/arm64/ ← ARM64 架构相关 ├── drivers/ ← ★ 所有驱动代码在这里 │ ├── gpio/ │ ├── i2c/ │ ├── spi/ │ ├── usb/ │ ├── sound/ ← Audio ASoC 驱动 │ ├── clk/ ← 时钟驱动 │ ├── regulator/ ← 电源驱动 │ └── ... └── include/ ← 公共头文件四. 内核启动时序内核只有一个进程所有的线程通过Kthread进行创建。大多数驱动的入口都为device_initcall() 中的module_init()。// [1] ABL 跳转入口 LinuxKernel(DeviceTreeLoadAddr, 0, 0, 0) // Bootloader └- arch/arm64/kernel/head.S primary_entry() // CPU 模式设置, MMU 关闭 └- __primary_switched() // 切换到虚拟地址, 设置 sp/ttbr └- start_kernel() // init/main.c, 第一个 C 函数 // [2] start_kernel() - init/main.c start_kernel() ├- set_task_stack_end_magic(init_task) // 设置栈溢出魔数 0x57AC6E9D ├- smp_setup_processor_id() // 读 MPIDR, Boot CPU 映射为逻辑 CPU0 ├- boot_cpu_init() // 设置 cpu_online/active/present/poss ├- page_address_init() ├- early_security_init() // LSM 早期初始化 ├- setup_arch(command_line) // ARM64 架构初始化 (DDR/DTB/内存布局) │ ├- setup_machine_fdt() // 解析 DTB, 获取 memory / chosen 节点 │ ├- early_fixmap_init() │ ├- arm64_memblock_init() // memblock 内存管理初始化 │ ├- paging_init() // 建立内核页表, 开启 MMU │ └- unflatten_device_tree() // 将 FDT 展开为 device_node 树 ├- setup_nr_cpu_ids() ├- setup_per_cpu_areas() // per-CPU 变量区域分配 ├- smp_prepare_boot_cpu() ├- boot_cpu_hotplug_init() ├- build_all_zonelists() // 内存 zone 初始化 ├- page_alloc_init() ├- parse_early_param() // 解析 earlycon 等 cmdline 早期参数 ├- mm_init() // Buddy allocator / vmalloc / slab 初 │ ├- mem_init() │ ├- kmem_cache_init() // SLAB/SLUB 分配器 │ └- vmalloc_init() ├- rcu_init() // RCU 子系统初始化 ├- init_IRQ() // GIC 中断控制器初始化, 建立 IRQ domain ├- tick_init() ├- timekeeping_init() ├- time_init() // ARM arch timer 注册, clocksource 初 ├- softirq_init() ├- perf_event_init() ├- acpi_early_init() ├- sched_init() // CFS 调度器初始化 ├- workqueue_init_early() ├- idr_init_cache() ├- signals_init() ├- seq_file_init() ├- proc_root_init() ├- vfs_caches_init_early() ├- vfs_caches_init() // VFS inode/dentry cache 初始化 ├- fork_init() // task_struct slab cache 初始化 ├- late_time_init() ├- calibrate_delay() // 计算 BogoMIPS └- rest_init() // 内核初始化最后一步 // [3] rest_init() - init/main.c rest_init() ├- kernel_thread(kernel_init, NULL, ...) // 创建 PID1, kernel_init 线程 ├- kernel_thread(kthreadd, NULL, ...) // 创建 PID2, kthreadd 内核线程守护进程 ├- schedule_preempt_disabled() // 触发一次调度, 切换到 kernel_init └- cpu_startup_entry(CPUHP_ONLINE) // Boot CPU 进入 idle 循环 (PID0) // [4] kernel_init() - PID1 kernel_init() ├- kernel_init_freeable() │ ├- do_pre_smp_initcalls() // 执行 early_initcall() 注册的函数 │ ├- smp_init() // 唤醒所有 Secondary CPU │ │ └- secondary_start_kernel() // 每个副核的入口 │ ├- sched_init_smp() │ ├- do_initcalls() // ★ 核心: 按优先级执行所有 initcall │ │ ├- pure_initcall() // level 0 │ │ ├- core_initcall() // level 1 │ │ ├- postcore_initcall() // level 2 │ │ ├- arch_initcall() // level 3 │ │ ├- subsys_initcall() // level 4 - 总线/子系统注册 │ │ ├- fs_initcall() // level 5 - 文件系统注册 │ │ ├- rootfs_initcall() // level rootfs │ │ ├- device_initcall() // level 6 - ★ module_init() 在此执行 │ │ └- late_initcall() // level 7 │ └- do_basic_setup() │ └- prepare_namespace() // 挂载 rootfs └- run_init_process(/sbin/init) // exec init, 内核线程转变为用户进程 └- /sbin/init (systemd / init.rc) // PID1 正式进入用户空间