linux启动时uboot传递进console=ttyS0,115200n8的参数
内核中用__setup()宏声明参数处理的方法
关于__setup宏参考 early_param和__setup宏
__setup("console=", console_setup);
console_setup函数处理
1.console_cmdline结构体
struct console_cmdline
{
char name[8]; //驱动名
int index; //次设备号
char *options; //选项
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
char *brl_options;
#endif
};
2.console_setup
static int __init console_setup(char *str)
{
char buf[sizeof(console_cmdline[0].name) + 4]; //分配驱动名+index的缓冲区
char *s, *options, *brl_options = NULL;
int idx;
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
if (!memcmp(str, "brl,", 4)) {
brl_options = "";
str += 4;
} else if (!memcmp(str, "brl=", 4)) {
brl_options = str + 4;
str = strchr(brl_options, ',');
if (!str) {
printk(KERN_ERR "need port name after brl=\n");
return 1;
}
*(str++) = 0;
}
#endif
if (str[0] >= '0' && str[0] <= '9') { //第一个参数属于[0,9]
strcpy(buf, "ttyS"); //则将其驱动名设为ttyS
strncpy(buf + 4, str, sizeof(buf) - 5);//将次设备号放其后面
} else {
strncpy(buf, str, sizeof(buf) - 1); //放设备号到其后面
}
buf[sizeof(buf) - 1] = 0;
if ((options = strchr(str, ',')) != NULL) //获取options
*(options++) = 0;
#ifdef __sparc__
if (!strcmp(str, "ttya"))
strcpy(buf, "ttyS0");
if (!strcmp(str, "ttyb"))
strcpy(buf, "ttyS1");
#endif
for (s = buf; *s; s++)
if ((*s >= '0' && *s <= '9') || *s == ',')
break;
idx = simple_strtoul(s, NULL, 10); //获取次设备号
*s = 0;
__add_preferred_console(buf, idx, options, brl_options);
console_set_on_cmdline = 1;
return 1;
}
__add_preferred_console函数
static int __add_preferred_console(char *name, int idx, char *options,char *brl_options)
{
struct console_cmdline *c;
int i;
for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) //可以最多8个console
if (strcmp(console_cmdline[i].name, name) == 0 && console_cmdline[i].index == idx) {
//比较已注册的console_cmdline数组中的项的名字及次设备号,若console_cmdline已经存在
if (!brl_options)
selected_console = i; //设置全局selected_console索引号
return 0; //则返回
}
if (i == MAX_CMDLINECONSOLES) //判断console_cmdline数组是否满了
return -E2BIG;
if (!brl_options)
selected_console = i; //设置全局selected_console索引号
c = &console_cmdline[i]; //获取全局console_cmdline数组的第i项地址
strlcpy(c->name, name, sizeof(c->name)); //填充全局console_cmdline的驱动名
c->options = options; //填充配置选项115200n8
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
c->brl_options = brl_options;
#endif
c->index = idx; //填充索引号0
return 0;
}
整体的作用是根据uboot传递的参数设置全局console_cmdline数组
该数组及全局selected_console,在register_console中会使用到
二 console 设备驱动