os/fs/sysfs/builders/
devices.rs

1//! /sys/devices/ 设备层次结构构建器
2//!
3//! 实现 Linux sysfs 规范的设备树结构,所有设备的真实目录都在 /sys/devices/ 下
4
5use alloc::format;
6use alloc::string::ToString;
7use alloc::sync::Arc;
8
9use crate::fs::sysfs::device_registry;
10use crate::fs::sysfs::inode::{SysfsAttr, SysfsInode};
11use crate::vfs::{FileMode, FsError, Inode};
12
13/// 构建 /sys/devices/ 层次结构
14pub fn build_platform_devices(root: &Arc<SysfsInode>) -> Result<(), FsError> {
15    // 获取 /sys/devices/
16    let devices_inode = root.lookup("devices")?;
17    let devices_dir = devices_inode
18        .downcast_ref::<SysfsInode>()
19        .ok_or(FsError::InvalidArgument)?;
20
21    // 创建 /sys/devices/platform/
22    let platform_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
23    devices_dir.add_child("platform", platform_dir.clone())?;
24
25    // 构建块设备
26    build_platform_block_devices(&platform_dir)?;
27
28    // 构建网络设备
29    build_platform_net_devices(&platform_dir)?;
30
31    // 构建 TTY 设备
32    build_platform_tty_devices(&platform_dir)?;
33
34    // 构建输入设备
35    build_platform_input_devices(&platform_dir)?;
36
37    // 构建 RTC 设备
38    build_platform_rtc_devices(&platform_dir)?;
39
40    Ok(())
41}
42
43/// 构建平台块设备
44fn build_platform_block_devices(platform_dir: &Arc<SysfsInode>) -> Result<(), FsError> {
45    for dev_info in device_registry::list_block_devices() {
46        // 创建设备目录 /sys/devices/platform/vda/
47        let dev_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
48
49        // dev 文件: major:minor
50        let dev_attr = SysfsAttr {
51            name: "dev".to_string(),
52            mode: FileMode::from_bits_truncate(0o444),
53            show: {
54                let maj = dev_info.major;
55                let min = dev_info.minor;
56                Arc::new(move || Ok(format!("{}:{}\n", maj, min)))
57            },
58            store: None,
59        };
60        dev_dir.add_child("dev", SysfsInode::new_attribute(dev_attr))?;
61
62        // uevent 文件
63        let uevent_attr = SysfsAttr {
64            name: "uevent".to_string(),
65            mode: FileMode::from_bits_truncate(0o644),
66            show: {
67                let maj = dev_info.major;
68                let min = dev_info.minor;
69                let name = dev_info.name.clone();
70                Arc::new(move || {
71                    Ok(format!(
72                        "MAJOR={}\nMINOR={}\nDEVNAME={}\nDEVTYPE=disk\n",
73                        maj, min, name
74                    ))
75                })
76            },
77            store: None,
78        };
79        dev_dir.add_child("uevent", SysfsInode::new_attribute(uevent_attr))?;
80
81        // size 文件: 扇区数 (512 字节)
82        let size_attr = SysfsAttr {
83            name: "size".to_string(),
84            mode: FileMode::from_bits_truncate(0o444),
85            show: {
86                let dev = dev_info.device.clone();
87                Arc::new(move || {
88                    let block_size = dev.block_size();
89                    let total_blocks = dev.total_blocks();
90                    let total_bytes = block_size * total_blocks;
91                    let sectors = total_bytes / 512;
92                    Ok(format!("{}\n", sectors))
93                })
94            },
95            store: None,
96        };
97        dev_dir.add_child("size", SysfsInode::new_attribute(size_attr))?;
98
99        // ro 文件: 是否只读
100        let ro_attr = SysfsAttr {
101            name: "ro".to_string(),
102            mode: FileMode::from_bits_truncate(0o444),
103            show: Arc::new(|| Ok("0\n".to_string())),
104            store: None,
105        };
106        dev_dir.add_child("ro", SysfsInode::new_attribute(ro_attr))?;
107
108        // removable 文件: 是否可移动
109        let removable_attr = SysfsAttr {
110            name: "removable".to_string(),
111            mode: FileMode::from_bits_truncate(0o444),
112            show: Arc::new(|| Ok("0\n".to_string())),
113            store: None,
114        };
115        dev_dir.add_child("removable", SysfsInode::new_attribute(removable_attr))?;
116
117        // stat 文件: I/O 统计信息
118        let stat_attr = SysfsAttr {
119            name: "stat".to_string(),
120            mode: FileMode::from_bits_truncate(0o444),
121            show: Arc::new(|| {
122                // 格式: read I/Os, read merges, read sectors, read ticks, write I/Os, ...
123                // 对于冷启动,返回全零统计
124                Ok("       0        0        0        0        0        0        0        0        0        0        0\n".to_string())
125            }),
126            store: None,
127        };
128        dev_dir.add_child("stat", SysfsInode::new_attribute(stat_attr))?;
129
130        // 创建 queue/ 子目录
131        build_queue_directory(&dev_dir, &dev_info.device)?;
132
133        // 添加到 platform 目录
134        platform_dir.add_child(&dev_info.name, dev_dir)?;
135    }
136
137    Ok(())
138}
139
140/// 构建块设备的 queue/ 子目录
141fn build_queue_directory(
142    dev_dir: &Arc<SysfsInode>,
143    device: &Arc<dyn crate::device::block::BlockDriver>,
144) -> Result<(), FsError> {
145    let queue_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
146
147    // logical_block_size
148    let logical_block_size_attr = SysfsAttr {
149        name: "logical_block_size".to_string(),
150        mode: FileMode::from_bits_truncate(0o444),
151        show: {
152            let dev = device.clone();
153            Arc::new(move || Ok(format!("{}\n", dev.block_size())))
154        },
155        store: None,
156    };
157    queue_dir.add_child(
158        "logical_block_size",
159        SysfsInode::new_attribute(logical_block_size_attr),
160    )?;
161
162    // physical_block_size
163    let physical_block_size_attr = SysfsAttr {
164        name: "physical_block_size".to_string(),
165        mode: FileMode::from_bits_truncate(0o444),
166        show: {
167            let dev = device.clone();
168            Arc::new(move || Ok(format!("{}\n", dev.block_size())))
169        },
170        store: None,
171    };
172    queue_dir.add_child(
173        "physical_block_size",
174        SysfsInode::new_attribute(physical_block_size_attr),
175    )?;
176
177    // hw_sector_size
178    let hw_sector_size_attr = SysfsAttr {
179        name: "hw_sector_size".to_string(),
180        mode: FileMode::from_bits_truncate(0o444),
181        show: Arc::new(|| Ok("512\n".to_string())),
182        store: None,
183    };
184    queue_dir.add_child(
185        "hw_sector_size",
186        SysfsInode::new_attribute(hw_sector_size_attr),
187    )?;
188
189    // max_sectors_kb
190    let max_sectors_kb_attr = SysfsAttr {
191        name: "max_sectors_kb".to_string(),
192        mode: FileMode::from_bits_truncate(0o644),
193        show: Arc::new(|| Ok("1280\n".to_string())), // 默认值
194        store: None,
195    };
196    queue_dir.add_child(
197        "max_sectors_kb",
198        SysfsInode::new_attribute(max_sectors_kb_attr),
199    )?;
200
201    // rotational (0 = SSD, 1 = HDD)
202    let rotational_attr = SysfsAttr {
203        name: "rotational".to_string(),
204        mode: FileMode::from_bits_truncate(0o644),
205        show: Arc::new(|| Ok("1\n".to_string())), // 假设为 HDD
206        store: None,
207    };
208    queue_dir.add_child("rotational", SysfsInode::new_attribute(rotational_attr))?;
209
210    dev_dir.add_child("queue", queue_dir)?;
211    Ok(())
212}
213
214/// 构建平台网络设备
215fn build_platform_net_devices(platform_dir: &Arc<SysfsInode>) -> Result<(), FsError> {
216    for dev_info in device_registry::list_net_devices() {
217        // 创建设备目录 /sys/devices/platform/eth0/
218        let dev_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
219
220        // uevent 文件
221        let uevent_attr = SysfsAttr {
222            name: "uevent".to_string(),
223            mode: FileMode::from_bits_truncate(0o644),
224            show: {
225                let name = dev_info.name.clone();
226                let ifindex = dev_info.ifindex;
227                Arc::new(move || Ok(format!("INTERFACE={}\nIFINDEX={}\n", name, ifindex)))
228            },
229            store: None,
230        };
231        dev_dir.add_child("uevent", SysfsInode::new_attribute(uevent_attr))?;
232
233        // address 文件: MAC 地址
234        let address_attr = SysfsAttr {
235            name: "address".to_string(),
236            mode: FileMode::from_bits_truncate(0o444),
237            show: {
238                let dev = dev_info.device.clone();
239                Arc::new(move || {
240                    let mac = dev.mac_address();
241                    Ok(format!(
242                        "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}\n",
243                        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
244                    ))
245                })
246            },
247            store: None,
248        };
249        dev_dir.add_child("address", SysfsInode::new_attribute(address_attr))?;
250
251        // mtu 文件
252        let mtu_attr = SysfsAttr {
253            name: "mtu".to_string(),
254            mode: FileMode::from_bits_truncate(0o644),
255            show: {
256                let dev = dev_info.device.clone();
257                Arc::new(move || Ok(format!("{}\n", dev.mtu())))
258            },
259            store: None,
260        };
261        dev_dir.add_child("mtu", SysfsInode::new_attribute(mtu_attr))?;
262
263        // operstate 文件
264        let operstate_attr = SysfsAttr {
265            name: "operstate".to_string(),
266            mode: FileMode::from_bits_truncate(0o444),
267            show: Arc::new(|| Ok("up\n".to_string())),
268            store: None,
269        };
270        dev_dir.add_child("operstate", SysfsInode::new_attribute(operstate_attr))?;
271
272        // carrier 文件: 物理链接状态
273        let carrier_attr = SysfsAttr {
274            name: "carrier".to_string(),
275            mode: FileMode::from_bits_truncate(0o444),
276            show: Arc::new(|| Ok("1\n".to_string())), // 1 = link up
277            store: None,
278        };
279        dev_dir.add_child("carrier", SysfsInode::new_attribute(carrier_attr))?;
280
281        // ifindex 文件: 接口索引
282        let ifindex_attr = SysfsAttr {
283            name: "ifindex".to_string(),
284            mode: FileMode::from_bits_truncate(0o444),
285            show: {
286                let ifindex = dev_info.ifindex;
287                Arc::new(move || Ok(format!("{}\n", ifindex)))
288            },
289            store: None,
290        };
291        dev_dir.add_child("ifindex", SysfsInode::new_attribute(ifindex_attr))?;
292
293        // type 文件: 设备类型 (1 = 以太网)
294        let type_attr = SysfsAttr {
295            name: "type".to_string(),
296            mode: FileMode::from_bits_truncate(0o444),
297            show: Arc::new(|| Ok("1\n".to_string())), // ARPHRD_ETHER
298            store: None,
299        };
300        dev_dir.add_child("type", SysfsInode::new_attribute(type_attr))?;
301
302        // 添加到 platform 目录
303        platform_dir.add_child(&dev_info.name, dev_dir)?;
304    }
305
306    Ok(())
307}
308
309/// 构建平台 TTY 设备
310fn build_platform_tty_devices(platform_dir: &Arc<SysfsInode>) -> Result<(), FsError> {
311    for dev_info in device_registry::list_tty_devices() {
312        // 创建设备目录 /sys/devices/platform/console/ 等
313        let dev_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
314
315        // dev 文件: major:minor
316        let dev_attr = SysfsAttr {
317            name: "dev".to_string(),
318            mode: FileMode::from_bits_truncate(0o444),
319            show: {
320                let maj = dev_info.major;
321                let min = dev_info.minor;
322                Arc::new(move || Ok(format!("{}:{}\n", maj, min)))
323            },
324            store: None,
325        };
326        dev_dir.add_child("dev", SysfsInode::new_attribute(dev_attr))?;
327
328        // uevent 文件
329        let uevent_attr = SysfsAttr {
330            name: "uevent".to_string(),
331            mode: FileMode::from_bits_truncate(0o644),
332            show: {
333                let maj = dev_info.major;
334                let min = dev_info.minor;
335                let name = dev_info.name.clone();
336                Arc::new(move || Ok(format!("MAJOR={}\nMINOR={}\nDEVNAME={}\n", maj, min, name)))
337            },
338            store: None,
339        };
340        dev_dir.add_child("uevent", SysfsInode::new_attribute(uevent_attr))?;
341
342        // 添加到 platform 目录
343        platform_dir.add_child(&dev_info.name, dev_dir)?;
344    }
345
346    Ok(())
347}
348
349/// 构建平台输入设备
350fn build_platform_input_devices(platform_dir: &Arc<SysfsInode>) -> Result<(), FsError> {
351    for dev_info in device_registry::list_input_devices() {
352        // 创建设备目录 /sys/devices/platform/input0/ 等
353        let dev_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
354
355        // uevent 文件
356        let uevent_attr = SysfsAttr {
357            name: "uevent".to_string(),
358            mode: FileMode::from_bits_truncate(0o644),
359            show: {
360                let name = dev_info.name.clone();
361                Arc::new(move || Ok(format!("NAME={}\n", name)))
362            },
363            store: None,
364        };
365        dev_dir.add_child("uevent", SysfsInode::new_attribute(uevent_attr))?;
366
367        // name 文件
368        let name_attr = SysfsAttr {
369            name: "name".to_string(),
370            mode: FileMode::from_bits_truncate(0o444),
371            show: {
372                let name = dev_info.name.clone();
373                Arc::new(move || Ok(format!("{}\n", name)))
374            },
375            store: None,
376        };
377        dev_dir.add_child("name", SysfsInode::new_attribute(name_attr))?;
378
379        // 添加到 platform 目录
380        platform_dir.add_child(&dev_info.name, dev_dir)?;
381    }
382
383    Ok(())
384}
385
386/// 构建平台 RTC 设备
387fn build_platform_rtc_devices(platform_dir: &Arc<SysfsInode>) -> Result<(), FsError> {
388    for dev_info in device_registry::list_rtc_devices() {
389        // 创建设备目录 /sys/devices/platform/rtc0/ 等
390        let dev_dir = SysfsInode::new_directory(FileMode::from_bits_truncate(0o040000 | 0o555));
391
392        // uevent 文件
393        let uevent_attr = SysfsAttr {
394            name: "uevent".to_string(),
395            mode: FileMode::from_bits_truncate(0o644),
396            show: {
397                let name = dev_info.name.clone();
398                Arc::new(move || Ok(format!("RTC_NAME={}\n", name)))
399            },
400            store: None,
401        };
402        dev_dir.add_child("uevent", SysfsInode::new_attribute(uevent_attr))?;
403
404        // name 文件
405        let name_attr = SysfsAttr {
406            name: "name".to_string(),
407            mode: FileMode::from_bits_truncate(0o444),
408            show: {
409                let name = dev_info.name.clone();
410                Arc::new(move || Ok(format!("{}\n", name)))
411            },
412            store: None,
413        };
414        dev_dir.add_child("name", SysfsInode::new_attribute(name_attr))?;
415
416        // date 文件: 读取当前 RTC 日期(北京时间)
417        let date_attr = SysfsAttr {
418            name: "date".to_string(),
419            mode: FileMode::from_bits_truncate(0o444),
420            show: {
421                let rtc = dev_info.device.clone();
422                Arc::new(move || {
423                    let dt = rtc.read_datetime();
424                    Ok(format!("{:04}-{:02}-{:02}\n", dt.year, dt.month, dt.day))
425                })
426            },
427            store: None,
428        };
429        dev_dir.add_child("date", SysfsInode::new_attribute(date_attr))?;
430
431        // time 文件: 读取当前 RTC 时间(北京时间)
432        let time_attr = SysfsAttr {
433            name: "time".to_string(),
434            mode: FileMode::from_bits_truncate(0o444),
435            show: {
436                let rtc = dev_info.device.clone();
437                Arc::new(move || {
438                    let dt = rtc.read_datetime();
439                    Ok(format!(
440                        "{:02}:{:02}:{:02}\n",
441                        dt.hour, dt.minute, dt.second
442                    ))
443                })
444            },
445            store: None,
446        };
447        dev_dir.add_child("time", SysfsInode::new_attribute(time_attr))?;
448
449        // 添加到 platform 目录
450        platform_dir.add_child(&dev_info.name, dev_dir)?;
451    }
452
453    Ok(())
454}