linux启动start_kernel之console_init

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比较,如果相符,就
从这个控制台输出。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值