glibc
printf ("hello Worldn"); // 过程和 echo "hello World" > /dev/console 一致
...
write(1,"hello Worldn",sizeof("hello Worldn"));
svc ...
linux
SYSCALL_DEFINE3(write // fs/read_write.c
ksys_write
vfs_write
file->f_op->write_iter/即redirected_tty_write
tty_write
n_tty_write
tty->ops->write/对于串口即uart_write
__uart_start.isra.1
pl011_start_tx
l2c210_sync
redirected_tty_write 与 文件系统
drivers/tty/tty_io.c
static const struct file_operations console_fops = {
.write_iter = redirected_tty_write,
tty_init
cdev_init(&console_cdev, &console_fops);
cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1);
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console");
consdev = device_create_with_groups(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, cons_dev_groups, "console");
问题
为什么printf底层的 redirected_tty_write 属于 cdev ,该cdev 和 /dev/console 有关系
那么 printf 用的 fd 1 和 /dev/console 有什么关系
我追到过 打开 /dev/console 的 过程, 明白 特殊文件系统 中 在open时替换了 file_operations
但是 printf 为什么 也能够调用到 redirected_tty_write?
fd 0 1 2 在进程创建的时候 就存在了 ,
我们明白,打开文件才会创建 fd,并会创建 struct file , 并填充 file->f_op->write_iter
所以可以说 是进程创建的时候 做了 这个 填充
进程创建的时候 只是做了 copy_files ,所以还是要看 init 进程的 file 配置
init 的file 配置 可以在启动时找到
在 kernel_init_freeable 中 调用了 console_on_rootfs
在 console_on_rootfs 中 ,打开了 /dev/console , 并 dup 出了 0 1 2
所以 0 1 2 对应的文件 都是 /dev/console
所以 printf 够调用到 /dev/console 对应的 redirected_tty_write 就 顺理成章了
上一篇:OK6410A 开发板 (八) 102 linux-5.11 OK6410A glibc提供的mmap的四种用途之一
下一篇:OK6410A 开发板 (八) 100 linux-5.11 OK6410A 内核空间虚拟内存布局
设计资源 培训 开发板 精华推荐
- CH55x系列简易下载器
- ADM8612 超低电压监控器的典型应用电路
- 使用 Analog Devices 的 LTC3603EMSE 的参考设计
- LT4275CIMS IEEE 802.3af(类型 1)13W 受电设备的典型应用电路
- EVAL-ADuC847QSZ,用于 ADuC848 微转换器 MCU 的 ADuC8xx 评估套件
- AT91SAM7L-EK,评估套件设计用于基于 AT91SAM7L ARM7 MCU 的应用
- 使用 MaxLinear, Inc 的 SPX2951 的参考设计
- 使用 CY3273 板的电力线通信 (PLC) 应用电路
- 雕刻机2.0
- RD-495,将 FSQ510 电源开关用于辅助电源应用的参考设计