您的位置:首页 > 运维架构 > Linux

linux启动start_kernel之console_init

2016-05-15 00:13 951 查看

linux启动start_kernel之console_init

asmlinkage void __init start_kernel(void)
printk(KERN_NOTICE "%s", linux_banner);
setup_arch(&command_line);//获取command_line
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);

console_init(); //控制台初始化

//setup_arch
//1.获取并解析cmdline
//2.设置页表
//3.初始化一些板级硬件
void __init setup_arch(char **cmdline_p)
mdesc = setup_machine(machine_arch_type);
if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params); //获取tag的虚拟地址
if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks != 0)
squash_mem_tags(tags);
save_atags(tags);
parse_tags(tags);//parse_tags
}

paging_init(mdesc);
devicemaps_init(mdesc);
if (mdesc->map_io)
mdesc->map_io();

//对于smdkc100
static void __init smdkc100_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(12000000);//初始化时钟
s3c24xx_init_uarts(smdkc100_uartcfgs,
ARRAY_SIZE(smdkc100_uartcfgs));//初始化串口
}

//对于tty
void __init console_init(void)
call = __con_initcall_start;
while (call < __con_initcall_end) {
(*call)();
call++;
}

__con_initcall_start,__con_initcall_end 在哪儿定义
grep -r "__con_initcall_start" ./

./arch/cris/kernel/vmlinux.lds.S
__con_initcall_start = .; *(.con_initcall.init) __con_initcall_end = .;

.con_initcall.init 在哪儿定义
grep -r ".con_initcall.init" ./
./include/linux/init.h
#define console_initcall(fn) \
static initcall_t __initcall_##fn \
__used __section(.con_initcall.init) = fn

//console_initcall宏,例如。
console_initcall(serial8250_console_init);
static initcall_t __initcall_serial8250_console_init __used __section(.con_initcall.init) = serial8250_console_init ;

对于s3c24xx平台
console_initcall(s3c_serial_console_init)
static struct console s3c24xx_serial_console = {
.name       = S3C24XX_SERIAL_NAME,
.device     = uart_console_device,
.flags      = CON_PRINTBUFFER,
.index      = -1,
.write      = s3c24xx_serial_console_write,
.setup      = s3c24xx_serial_console_setup
};

int s3c24xx_serial_initconsole(struct platform_driver *drv,
struct s3c24xx_uart_info **info)
{
register_console(&s3c24xx_serial_console);
return 0;
}

//根据register_console来选择终端
void register_console(struct console *newcon)
if (strcmp(console_cmdline[i].name, newcon->name) != 0) //名字匹配
continue;
if (newcon->index < 0)
newcon->index = console_cmdline[i].index;//index
newcon->setup(newcon, console_cmdline[i].options) //更具cmdline 设置serial


总结:

xxxx_serial_console结构链入全局链表console_driver中,并且与启动参数

console=ttySAC0和struct console中的name与index比较,如果相符,就

从这个控制台输出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: