我正在阅读Linux的源代码,希望能够更好地理解它的架构。我的目标是将其减少到最小的“hello,world”二进制文件,并删除尽可能多的不相关代码。这是我在写这个问题时正在研究的版本:
https://github.com/d33tah/minimal-kernel-build/tree/feb6e7/minified
我有一个最小的 initrd,它通过 sys_write 系统调用将“Hello, world”打印到 VGA 控制台。我正在寻找将字符发送到 VGA 设备的例程。在查看 vgacon.c 时,我发现了以下内容:
const struct consw vga_con = {
.owner = THIS_MODULE,
.con_startup = vgacon_startup,
.con_init = vgacon_init,
.con_deinit = vgacon_deinit,
.con_clear = vgacon_clear,
.con_putc = vgacon_putc,
.con_putcs = vgacon_putcs,
.con_cursor = vgacon_cursor,
.con_scroll = vgacon_scroll,
.con_switch = vgacon_switch,
.con_blank = vgacon_blank,
.con_font_set = vgacon_font_set,
.con_font_get = vgacon_font_get,
.con_resize = vgacon_resize,
.con_set_palette = vgacon_set_palette,
.con_scrolldelta = vgacon_scrolldelta,
.con_set_origin = vgacon_set_origin,
.con_save_screen = vgacon_save_screen,
.con_build_attr = vgacon_build_attr,
.con_invert_region = vgacon_invert_region,
};
EXPORT_SYMBOL(vga_con);
不幸的是,唯一不言自明的函数是 vgacon_putc 和 vgacon_putcs,它们被显式定义为空:
drivers/video/console/vgacon.c:1188:static void vgacon_putc(struct vc_data *vc, int c, int ypos, int xpos) { }
drivers/video/console/vgacon.c:1189:static void vgacon_putcs(struct vc_data *vc, const unsigned short *s,
drivers/video/console/vgacon.c-1190- int count, int ypos, int xpos) { }
我尝试向此处公开的大多数函数添加额外的“返回”,以找到必要的函数并阅读破坏流程的函数,但我找不到任何明显的函数。这是在另一个文件中吗?为什么那些例程是空的? tty 代码是否直接将字符写入 vgacon 驱动程序使用的某个缓冲区?
正如用户 Ian Abbott 在他对这个问题的评论中指出的那样,我正在寻找的代码位于 vc_con_write_normal 中。那里有下面一行:
scr_writew(tc, (u16 *)vc->vc_pos);
注释掉它会禁用输出。它的定义如下:
include/linux/vt_buffer.h
#define scr_writew(val, addr) (*(addr) = (val))