1 通用基础设施 API
1.1 内存分配与拷贝
| API | 说明 | 上下文 |
|---|---|---|
kmalloc(size, gfp) / kzalloc() |
物理连续,小对象(≤ 几页) | 可睡眠(GFP_KERNEL)或原子 |
kcalloc(n, size, gfp) |
数组分配并清零 | 同上 |
vmalloc(size) / vzalloc() |
虚拟连续,物理可不连续 | 可睡眠 |
devm_kzalloc(dev, size, gfp) |
绑定设备,自动回收 | 可睡眠(probe) |
__get_free_pages(gfp, order) |
按页分配 | 视 gfp |
kfree() / vfree() |
释放 | 同上 |
copy_to_user() / copy_from_user() |
内核<->用户拷贝 | 可睡眠 |
kmemdup() |
分配并拷贝 | 可睡眠 |
1.2 引用计数与原子
| API | 说明 |
|---|---|
kref_init()/kref_get()/kref_put() |
引用计数对象 |
refcount_set()/refcount_inc()/refcount_dec_and_test() |
防溢出引用计数 |
atomic_read/set/inc/dec/add/sub |
atomic_t 操作 |
atomic_dec_and_test()/atomic_inc_return() |
复合原子操作 |
atomic_cmpxchg()/atomic_xchg() |
CAS/交换 |
set_bit/clear_bit/test_and_set_bit/test_and_clear_bit |
位原子操作 |
READ_ONCE()/WRITE_ONCE() |
抑制编译器优化 |
smp_mb()/smp_rmb()/smp_wmb()/barrier() |
内存屏障 |
1.3 容器与时间
| API | 说明 |
|---|---|
container_of(ptr, type, member) |
从成员反推结构体 |
list_add/list_add_tail/list_del/list_for_each_entry |
双向链表 |
INIT_LIST_HEAD() |
初始化链表头 |
jiffies/HZ/msecs_to_jiffies() |
节拍与换算 |
ktime_get()/ktime_get_ns() |
单调时间 |
usleep_range()/msleep()/ssleep() |
睡眠延时 |
udelay()/ndelay()/mdelay() |
忙等延时 |
1.4 并发与锁
| API | 说明 |
|---|---|
spin_lock_init()/spin_lock()/spin_unlock() |
自旋锁(不可睡眠) |
spin_lock_irqsave()/spin_unlock_irqrestore() |
关中断版自旋锁 |
spin_lock_bh()/spin_unlock_bh() |
关软中断版 |
rwlock_t + read_lock/write_lock |
读写自旋锁 |
seqlock_t + write_seqlock/read_seqbegin |
顺序锁 |
mutex_init()/mutex_lock()/mutex_unlock() |
互斥体(可睡眠) |
down()/up() / struct semaphore |
信号量(遗留) |
init_completion()/wait_for_completion()/complete() |
完成量 |
rcu_read_lock()/rcu_read_unlock()/synchronize_rcu() |
RCU |
guard(mutex)(&m->lock) / scoped_guard() |
cleanup.h 作用域锁(7.2.5 新) |
2 子系统 API
2.1 字符设备与文件操作
| API | 说明 |
|---|---|
alloc_chrdev_region()/register_chrdev_region() |
动态/静态申请设备号 |
unregister_chrdev_region() |
释放设备号 |
cdev_init()/cdev_add()/cdev_del() |
字符设备注册 |
MAJOR()/MINOR()/MKDEV() |
设备号运算 |
class_create(name) |
单参数(7.2.5) |
device_create()/device_destroy() |
创建设备节点 |
struct file_operations |
open/read/write/unlocked_ioctl/poll/mmap/fasync |
nonseekable_open()/no_llseek |
不支持 seek 的文件 |
simple_read_from_buffer()/simple_write_to_buffer() |
简化 read/write |
struct miscdevice + misc_register()/misc_deregister() |
杂项设备(10 号设备) |
strscpy() |
安全字符串拷贝(strlcpy 已删除) |
2.2 阻塞 / 非阻塞 / 异步
| API | 说明 |
|---|---|
wait_queue_head_t + init_waitqueue_head() |
等待队列 |
wait_event_interruptible()/wake_up_interruptible() |
阻塞与唤醒 |
poll_wait() + .poll 回调 |
轮询支持 |
fasync_helper() + .fasync 回调 |
异步通知注册 |
kill_fasync() |
发送 SIGIO |
fcntl(F_SETOWN)/FASYNC |
用户态异步通知 |
2.3 中断、定时器、工作队列
| API | 说明 |
|---|---|
request_irq()/request_threaded_irq()/devm_request_irq() |
申请中断 |
free_irq()/devm_free_irq() |
释放中断 |
enable_irq()/disable_irq()/disable_irq_nosync() |
使能/屏蔽中断 |
IRQF_SHARED/IRQF_ONESHOT/IRQF_TRIGGER_* |
中断标志 |
tasklet_setup()/tasklet_schedule() |
tasklet(遗留) |
INIT_WORK()/schedule_work()/cancel_work_sync() |
工作队列 |
INIT_DELAYED_WORK()/schedule_delayed_work() |
延迟工作 |
timer_setup()/add_timer()/mod_timer()/del_timer_sync() |
定时器(init_timer 已删除) |
hrtimer_init()/hrtimer_start() |
高精度定时器 |
2.4 内存 / I/O / DMA
| API | 说明 |
|---|---|
ioremap()/devm_ioremap()/ioremap_wc() |
映射 I/O 内存 |
devm_platform_ioremap_resource() |
platform 资源映射(推荐) |
readb/readw/readl / writeb/writew/writel |
I/O 内存读写 |
readl_relaxed()/writel_relaxed() |
无屏障版本 |
inb/outb/inl/outl |
I/O 端口读写 |
request_mem_region()/release_mem_region() |
申请 I/O 内存区域 |
request_region()/release_region() |
申请 I/O 端口区域 |
remap_pfn_range()/vmf_insert_pfn() |
内核页映射到用户空间 |
dma_alloc_coherent()/dma_free_coherent() |
一致性 DMA |
dma_map_single()/dma_unmap_single() |
流式 DMA |
dma_sync_single_for_cpu()/_for_device() |
流式 DMA 同步 |
dma_set_mask_and_coherent() |
设置 DMA 掩码 |
2.5 总线与设备模型
| API | 说明 |
|---|---|
platform_driver_register()/platform_driver_unregister() |
platform 驱动 |
module_platform_driver() |
platform 驱动宏 |
platform_get_resource()/platform_get_irq() |
获取资源 |
platform_set_drvdata()/platform_get_drvdata() |
私有数据 |
dev_err_probe() |
probe 错误打印(推荐) |
devm_*() 系列 |
设备托管资源自动回收 |
of_property_read_u32/u64/string() |
设备树属性读取 |
of_parse_phandle()/of_get_child_by_name() |
设备树节点查找 |
of_irq_get()/of_irq_count() |
设备树中断 |
of_reserved_mem_device_init() |
保留内存 |
regmap_init()/regmap_read()/regmap_write() |
寄存器抽象层 |
get_device()/put_device() |
设备引用计数 |
2.6 I²C
| API | 说明 |
|---|---|
i2c_add_adapter()/i2c_del_adapter() |
适配器注册 |
i2c_register_driver()/i2c_del_driver()/module_i2c_driver() |
设备驱动注册 |
i2c_transfer()/i2c_master_send()/i2c_master_recv() |
数据传输 |
i2c_new_client_device()/i2c_new_scanned_device() |
实例化 client |
i2c_get_adapter()/i2c_put_adapter() |
引用适配器 |
.probe(client) 单参数 / .remove 返回 void |
7.2.5 签名 |
2.7 SPI
| API | 说明 |
|---|---|
spi_alloc_host()/devm_spi_alloc_host() |
分配控制器(spi_controller) |
spi_register_controller()/spi_unregister_controller() |
控制器注册 |
spi_sync()/spi_sync_locked()/spi_async() |
传输 |
spi_message_init()/spi_message_add_tail() |
消息组装 |
spi_new_device()/spi_add_device() |
创建设备 |
.probe(spi) 单参数 / .remove 返回 void |
7.2.5 签名 |
2.8 USB
| API | 说明 |
|---|---|
usb_register_driver()/module_usb_driver() |
设备驱动注册 |
usb_alloc_urb()/usb_free_urb()/usb_submit_urb() |
URB |
usb_kill_urb()/usb_unlink_urb() |
取消 URB |
usb_fill_control_urb()/usb_fill_bulk_urb()/usb_fill_int_urb() |
填充 URB |
usb_control_msg()/usb_bulk_msg() |
同步传输 |
usb_register_dev()/usb_deregister_dev() |
注册字符接口 |
.probe(intf, id) 两参数 / .disconnect(intf) 返回 void |
7.2.5 签名 |
usb_endpoint_maxp()/usb_sndbulkpipe()/usb_rcvintpipe() |
端点辅助 |
2.9 块设备与网络
| API | 说明 |
|---|---|
blk_mq_alloc_tag_set()/blk_mq_free_tag_set() |
blk-mq 标签集 |
blk_mq_alloc_disk()/blk_mq_alloc_disk_for_queue() |
分配 gendisk |
add_disk()/del_gendisk()/put_disk() |
注册/注销磁盘 |
submit_bio 回调 / .queue_rq |
两种 I/O 路径 |
alloc_netdev()/alloc_etherdev()/free_netdev() |
分配 net_device |
register_netdev()/unregister_netdev() |
注册网络设备 |
netif_napi_add()/napi_schedule()/napi_complete_done() |
NAPI |
netif_carrier_on()/netif_carrier_off() |
链路状态 |
netif_rx()/netif_receive_skb() |
上交报文 |
ethtool_ops |
参数与统计 |
2.10 电源管理、时钟、GPIO
| API | 说明 |
|---|---|
cpu_latency_qos_add_request()/_update_request()/_remove_request() |
PM QoS(旧 pm_qos_add_request 已删) |
dev_pm_opp_find_freq_ceil()/dev_pm_opp_set_rate() |
OPP |
devm_pm_opp_set_config() |
OPP 配置 |
devm_pm_runtime_enable()/pm_runtime_resume_and_get() |
runtime PM |
SYSTEM_SLEEP_PM_OPS()/RUNTIME_PM_OPS()/DEFINE_SIMPLE_DEV_PM_OPS() |
PM 操作宏 |
devm_clk_get()/devm_clk_get_enabled()/devm_clk_get_prepared() |
时钟 |
devm_clk_hw_register_*()/devm_of_clk_add_hw_provider() |
CCF |
devm_regulator_get()/devm_regulator_get_enable() |
Regulator |
devm_gpiod_get()/devm_gpiod_get_optional() |
GPIO 描述符(gpiod_*) |
gpiod_get_value()/gpiod_set_value()/gpiod_to_irq() |
GPIO 读写与中断 |
devm_gpiochip_add_data() |
注册 GPIO 控制器 |
2.11 底层驱动(移植)
| API | 说明 |
|---|---|
clockevents_config_and_register() |
注册 clockevent |
clocksource_register_hz()/clocksource_register_khz() |
注册 clocksource |
TIMER_OF_DECLARE() |
设备树声明定时器 |
irq_domain_add_linear()/devm_irq_domain_create_linear() |
IRQ domain |
irq_create_mapping()/irq_find_mapping()/irq_set_chip_and_handler() |
中断映射 |
generic_handle_irq()/irq_set_chained_handler_and_data() |
级联中断 |
cpuhp_setup_state()/CPUHP_AP_ONLINE_DYN |
CPU 热插拔 |
dma_request_chan()/devm_dma_request_chan() |
DMA 通道 |
dmaengine_slave_config()/dmaengine_prep_slave_sg() |
DMA 配置 |
dmaengine_submit()/dma_async_issue_pending() |
DMA 提交 |
dmaengine_terminate_sync() |
终止(terminate_all 已弃用) |
2.12 调试与工具
| API / 工具 | 说明 |
|---|---|
pr_info()/pr_err()/dev_dbg()/dev_err() |
分级打印 |
dev_err_probe() |
probe 错误打印 |
pr_fmt() |
自定义打印前缀 |
proc_create() + struct proc_ops |
创建 /proc 节点(成员 proc_open/proc_read/proc_lseek/proc_release) |
debugfs_create_file()/debugfs_create_dir() |
debugfs 节点 |
dynamic_debug(CONFIG_DYNAMIC_DEBUG) |
运行时打开 pr_debug |
WARN_ON()/WARN_ON_ONCE()/BUG_ON() |
断言(优先 WARN) |
dump_stack() |
打印调用栈 |
scripts/checkpatch.pl |
风格检查 |
scripts/get_maintainer.pl |
找维护者 |
scripts/decode_stacktrace.sh/faddr2line |
解析 Oops |
scripts/gdb/(lx-*) |
内核 GDB 脚本 |
3 常用错误码
| 错误码 | 值 | 含义与场景 |
|---|---|---|
0 |
0 | 成功 |
-EINVAL |
-22 | 参数非法 |
-ENOMEM |
-12 | 内存不足 |
-EIO |
-5 | I/O 错误 |
-EOPNOTSUPP |
-95 | 操作不支持 |
-EAGAIN |
-11 | 暂时不可用(非阻塞) |
-EBUSY |
-16 | 设备忙 |
-ENODEV |
-19 | 无此设备 |
-ENOENT |
-2 | 无此条目 |
-EPROBE_DEFER |
-517 | probe 延后(依赖未就绪) |
-ESHUTDOWN |
-108 | 设备已关闭(如 USB 拔出) |
-ERESTARTSYS |
-512 | 被信号打断,重试系统调用 |
-ETIMEDOUT |
-110 | 超时 |
-ENOSYS |
-38 | 未实现 |
IS_ERR()/PTR_ERR()/ERR_PTR() 用于区分指针与错误码;PTR_ERR() 取负值,ERR_PTR(-ENOMEM) 造错误指针。
4 术语表
| 术语 | 全称 / 含义 |
|---|---|
| HCD | Host Controller Driver,USB 主机控制器驱动 |
| UDC | USB Device Controller,USB 设备(gadget)控制器 |
| URB | USB Request Block,USB 请求块 |
| Gadget | 设备侧 USB 驱动框架(让板子当外设) |
| Function | gadget 中的功能单元(ACM/MS/loopback...) |
| configfs | 用户空间通过文件系统配置 gadget |
| adapter | I²C/SPI 主机控制器实例 |
| client | 挂在 I²C/SPI 总线上的外设 |
| controller | 7.2.5 中 SPI 主机的正式名(旧名 master) |
| host | SPI/USB 主机侧 |
| OPP | Operating Performance Point,性能点(频率/电压对) |
| genpd | Generic Power Domain,通用电源域 |
| regmap | 寄存器映射抽象层(I²C/SPI/MMIO 统一) |
| nvmem | 非易失存储框架(EEPROM/OTP 等) |
| fwnode | 固件节点抽象(统一设备树 OF 与 ACPI) |
| irqdomain | 中断号映射域 |
| clockevent | 触发定时中断的时钟设备 |
| clocksource | 提供时间读数的时钟源 |
| CCF | Common Clock Framework,通用时钟框架 |
| pinctrl | pin 复用与配置子系统 |
| blk-mq | 多队列块层(现代唯一块 I/O 路径) |
| NAPI | 网络轮询 + 中断混合收包机制 |
| ethtool | 网络设备参数与统计接口 |
| XDP | eXpress Data Path,网卡驱动层高性能包处理 |
| DMA | Direct Memory Access,直接内存访问 |
| IOMMU | I/O 内存管理单元 |
| devm | device-managed,资源随设备自动回收 |
| SPDX | 许可证标识(SPDX-License-Identifier) |
| 9p / virtio-9p | QEMU 宿主-guest 共享目录协议 |
| gdbstub | QEMU 内置 GDB 服务端(-s/-S) |
| kgdboc | KGDB over Console,串口内核调试 |
5 实验环境检查表
在开始任何实验前,逐项确认:
| 检查项 | 命令 / 位置 | 期望 |
|---|---|---|
| 内核源码 | head -5 $KSRC/Makefile |
VERSION=7 PATCHLEVEL=2 SUBLEVEL=5 |
| 构建目录 | ls $KBUILD/arch/x86/boot/bzImage |
存在 |
| 配置文件 | ls $KBUILD/.config |
存在 |
| initramfs | ls $INITRD |
存在 |
| QEMU 可用 | qemu-system-x86_64 --version |
≥ 8.0 |
| QEMU 设备 | qemu-system-x86_64 -device help | grep virtio |
有 virtio 系列 |
| 交叉/本地工具链 | gcc --version / make --version |
可用 |
| 外部模块构建 | make -f $KDIR/Makefile M=$PWD modules |
生成 .ko |
| guest 启动 | QEMU 命令 | 打印 === Linux 7.2.5 QEMU initramfs === |
| guest 版本 | cat /proc/version |
含 7.2.5 |
| 模块加载 | insmod mydrv.ko && dmesg | tail |
打印 probe 日志 |
| 设备节点 | ls -l /dev/globalmem |
主次设备号正确 |
| debugfs | mount -t debugfs none /sys/kernel/debug |
可挂载 |
| configfs | mount -t configfs none /sys/kernel/config |
可挂载 |
| 模拟 I²C | modprobe i2c-stub chip_addr=0x50 |
生成 /dev/i2c-* |
| 模拟 GPIO | configfs gpio-sim live=1 |
生成 /dev/gpiochipN |
| 模拟 USB | modprobe dummy_hcd + configfs |
生成 UDC 与 gadget |
| 内核调试 | QEMU -s -S + gdb vmlinux |
可下断点 |
6 小结
- 本附录 API 均对照 7.2.5 源码核实;与旧书不一致处,以本表为准。
- 记住三条签名变化高频点:
class_create(name)单参数 、I²C/SPI probe 单参数 + remove void 、USB probe 仍两参数。 - 记住三条"已删除"接口:
init_timer、create_proc_read_entry、strlcpy(用timer_setup/proc_create+proc_ops/strscpy)。 - 错误码一律返回负值;
-EPROBE_DEFER是 probe 依赖未就绪的标准返回。 - 实验前先过一遍 5 检查表,可避免绝大多数"跑不起来"的问题。