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 设备驱动