在drivers/tty/vt.c中会通过console_initcall 来调用con_init,在con_init的最后如果有定义CONFIG_VT_CONSOLE的话,
#ifdef CONFIG_VT_CONSOLE
register_console(&vt_console_driver);
#endif
会调用register_console 来注册vt_console_driver。
static struct console vt_console_driver = {
.name = "tty",
.write = vt_console_print,
.device = vt_console_device,
.unblank = unblank_screen,
.flags = CON_PRINTBUFFER,
.index = -1,
};
注意这里的index是等于-1,flags为CON_PRINTBUFFER,但是match和setup函数为null。
这样当从setup_arch->acpi_boot_table_init->parse_spcr->add_preferred_console的时候会给selected_console 赋值,因为brl_options always是null的.
static int __add_preferred_console(char *name, int idx, char *options,
char *brl_options)
{
struct console_cmdline *c;
int i;
/*
* See if this tty is not yet registered, and
* if we have a slot free.
*/
for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
if (strcmp(c->name, name) == 0 && c->index == idx) {
if (!brl_options)
selected_console = i;
return 0;
}
}
if (i == MAX_CMDLINECONSOLES)
return -E2BIG;
if (!brl_options)
selected_console = i;
strlcpy(c->name, name, sizeof(c->name));
c->options = options;
braille_set_options(c, brl_options);
c->index = idx;
return 0;
}
由于parse_spcr的调用时间比con_init的时间早,这样当con_init在调用register_console的时候,由于preferred_console < 0 且 selected_console已经在__add_preferred_console 中赋值了,所以这里将
if (preferred_console < 0 || bcon || !console_drivers)
preferred_console = selected_console;
selected_console 赋值给preferred_console。
所以下面这个条件就不成立,所以不能将tty-1 改成tty0.所以这个时候VGA显示屏没有输出
if (preferred_console < 0) {
if (newcon->index < 0)
newcon->index = 0;
if (newcon->setup == NULL ||
newcon->setup(newcon, NULL) == 0) {
newcon->flags |= CON_ENABLED;
if (newcon->device) {
newcon->flags |= CON_CONSDEV;
preferred_console = 0;
}
}
}
既然parse_spcr调用时间比较早,这个时候只能在cmdline传递console=tty0.这样在register_console 中
for (i = 0, c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
if (!newcon->match ||
newcon->match(newcon, c->name, c->index, c->options) != 0) {
/* default matching */
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0)
continue;
if (newcon->index >= 0 &&
newcon->index != c->index)
continue;
if (newcon->index < 0)
newcon->index = c->index;
if (_braille_register_console(newcon, c))
return;
if (newcon->setup &&
newcon->setup(newcon, c->options) != 0)
break;
}
这个for循环中,由于vt_console_driver的match函数为null,因此if (!newcon->match ||
newcon->match(newcon, c->name, c->index, c->options) != 0)
这个条件成立,然后就会将tty-1,改成tty0,然后就可以在VGA上看到输出了。