graph TB
A["Linux 内核子系统"] --> B["设备驱动\n10-12 章"]
A --> C["网络栈\n13 章"]
B --> B1["字符设备"]
B --> B2["块设备"]
B --> B3["网络设备"]
C --> C1["socket 层"]
C --> C2["TCP/IP 协议"]
C --> C3["netfilter"]
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style B1 fill:#FFF9C4,stroke:#F9A825,color:#333
style B2 fill:#FFF9C4,stroke:#F9A825,color:#333
style B3 fill:#FFF9C4,stroke:#F9A825,color:#333
style C1 fill:#FFF9C4,stroke:#F9A825,color:#333
style C2 fill:#FFF9C4,stroke:#F9A825,color:#333
style C3 fill:#FFF9C4,stroke:#F9A825,color:#333
一、第 10 章:设备驱动程序
1.1 Linux 设备分类
graph TB
A["Linux 设备"] --> B["字符设备\nchar"]
A --> C["块设备\nblock"]
A --> D["网络设备\nnet"]
B --> B1["顺序访问\n键盘/串口/tty"]
C --> C1["随机访问\n磁盘/SSD"]
D --> D1["网络包\n网卡/loopback"]
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style D fill:#FFB3C6,stroke:#F48FB1,color:#333
style B1 fill:#FFF9C4,stroke:#F9A825,color:#333
style C1 fill:#FFF9C4,stroke:#F9A825,color:#333
style D1 fill:#FFF9C4,stroke:#F9A825,color:#333
1.2 设备驱动模型(核心)
graph TB
A["Linux 设备模型"] --> B["kobject\n基础对象"]
A --> C["kset\n对象集合"]
A --> D["ktype\n对象类型"]
A --> E["bus\n总线"]
A --> F["device\n设备"]
A --> G["device_driver\n驱动"]
B --> B1["引用计数\nsysfs 目录"]
E --> E1["匹配设备+驱动"]
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style D fill:#FFF9C4,stroke:#F9A825,color:#333
style E fill:#FFB3C6,stroke:#F48FB1,color:#333
style F fill:#B5EAD7,stroke:#80CBC4,color:#333
style G fill:#B5EAD7,stroke:#80CBC4,color:#333
style B1 fill:#FFF9C4,stroke:#F9A825,color:#333
style E1 fill:#FFF9C4,stroke:#F9A825,color:#333
graph TB
A["bus\n(如 PCI)"] --> B["device 1"]
A --> C["device 2"]
B --> D["driver 1\n匹配 device 1"]
B -.->|匹配| D
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#E8D5F5,stroke:#CE93D8,color:#333
style D fill:#B5EAD7,stroke:#80CBC4,color:#333
匹配流程:
graph TB
A["设备插入"] --> B["创建 device 对象"]
B --> C["遍历 bus 驱动"]
C --> D{"match() 成功?"}
D -->|"是"| E["调用 driver->probe()"]
D -->|"否"| F["设备无驱动"]
E --> G["设备可用"]
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style D fill:#FFF9C4,stroke:#F9A825,color:#333
style E fill:#B5EAD7,stroke:#80CBC4,color:#333
style F fill:#FFB3C6,stroke:#F48FB1,color:#333
style G fill:#B5EAD7,stroke:#80CBC4,color:#333
graph TB
A["应用层\nHTTP/SSH/DNS"] --> B["Socket 层\nBSD socket"]
B --> C["传输层\nTCP/UDP"]
C --> D["网络层\nIP/ICMP"]
D --> E["链路层\nEthernet/ARP"]
E --> F["物理层\n网卡驱动"]
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style D fill:#FFB3C6,stroke:#F48FB1,color:#333
style E fill:#B5EAD7,stroke:#80CBC4,color:#333
style F fill:#FFF9C4,stroke:#F9A825,color:#333
graph LR
A["head"] --> B["data"]
B --> C["tail"]
C --> D["end"]
A ---|"headroom\n协议头预留"| B
B ---|"实际数据\ndata_len"| C
C ---|"tailroom\n扩展空间"| D
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style D fill:#B5EAD7,stroke:#80CBC4,color:#333
关键操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 头部预留 skb_reserve(skb, headroom);
// 添加数据 skb_put(skb, len); // tail += len
// 移除数据 skb_pull(skb, len); // data += len(去掉头)
// 克隆 skb_clone(skb); // 浅拷贝
// 复制 skb_copy(skb); // 深拷贝
5.4 TCP/IP 数据包发送
sequenceDiagram
participant App as 应用
participant Sock as socket
participant TCP as TCP
participant IP as IP
participant Dev as 设备驱动
participant Nic as 网卡
App->>Sock: write(sock, data, len)
Sock->>TCP: tcp_sendmsg
TCP->>TCP: skb = alloc
TCP->>IP: ip_queue_xmit
IP->>IP: 添加 IP 头
IP->>Dev: dev_queue_xmit
Dev->>Dev: 添加 Ethernet 头
Dev->>Nic: DMA 发送
Nic-->>App: 发送完成
5.5 TCP/IP 数据包接收
sequenceDiagram
participant Nic as 网卡
participant Dev as 设备驱动
participant IP as IP
participant TCP as TCP
participant Sock as socket
participant App as 应用
Nic->>Dev: 接收中断
Dev->>Dev: 分配 skb,复制数据
Dev->>IP: netif_rx → ip_rcv
IP->>IP: 检查 IP 头
IP->>TCP: tcp_v4_rcv
TCP->>TCP: 三次握手/数据传输
TCP->>Sock: 加入接收队列
Sock->>App: read 返回
App-->>App: 处理数据
5.6 TCP 三次握手
sequenceDiagram
participant C as 客户端
participant S as 服务器
C->>S: SYN (seq=x)
S->>C: SYN+ACK (seq=y, ack=x+1)
C->>S: ACK (ack=y+1)
Note over C,S: 连接建立
5.7 关键启示
网络栈分层——Socket / TCP / IP / 驱动
sk_buff——包的核心,零拷贝的关键
TCP 三次握手——建立可靠连接
六、Netfilter 框架
6.1 Netfilter 5 个钩子点
graph TB
A["包进入"] --> B["NF_INET_PRE_ROUTING\n(路由前)"]
B --> C{"路由判断"}
C -->|"本地包"| D["NF_INET_LOCAL_IN\n(本地输入)"]
C -->|"转发包"| E["NF_INET_FORWARD\n(转发)"]
D --> F["应用处理"]
E --> G["NF_INET_POST_ROUTING\n(路由后)"]
F --> H["NF_INET_LOCAL_OUT\n(本地输出)"]
H --> I["包发出"]
G --> I
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFF9C4,stroke:#F9A825,color:#333
style D fill:#FFDAB9,stroke:#FFAB76,color:#333
style E fill:#FFDAB9,stroke:#FFAB76,color:#333
style F fill:#B5EAD7,stroke:#80CBC4,color:#333
style G fill:#FFB3C6,stroke:#F48FB1,color:#333
style H fill:#FFB3C6,stroke:#F48FB1,color:#333
style I fill:#C7CEEA,stroke:#9FA8DA,color:#333
graph TB
A["用户进程"] --> B["tty 核心\n(line discipline)"]
B --> C["tty 驱动"]
C --> D["硬件 UART"]
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style D fill:#FFB3C6,stroke:#F48FB1,color:#333
# 测试:阻止某个 IP sudo iptables -I INPUT -s 192.168.1.100 -j DROP
# 删除 sudo iptables -D INPUT -s 192.168.1.100 -j DROP
9.6 实验 6:netstat / ss
1 2 3 4 5 6 7 8
# 旧版 netstat -tan
# 新版(更快) ss -tan
# 详细 ss -tanp
十、回到 5 个核心要点
graph TB
A["驱动 + 网络栈核心"] --> B["设备模型\nkobject/bus/device/driver"]
A --> C["3 大设备类型\nchar/block/net"]
A --> D["网络栈分层\nsocket/TCP/IP/driver"]
A --> E["sk_buff\n零拷贝"]
A --> F["netfilter\n5 钩子点"]
style A fill:#C7CEEA,stroke:#9FA8DA,color:#333
style B fill:#E8D5F5,stroke:#CE93D8,color:#333
style C fill:#FFDAB9,stroke:#FFAB76,color:#333
style D fill:#FFB3C6,stroke:#F48FB1,color:#333
style E fill:#B5EAD7,stroke:#80CBC4,color:#333
style F fill:#FFF9C4,stroke:#F9A825,color:#333