歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> linux啟動start_kernel之console_init

linux啟動start_kernel之console_init

日期:2017/3/3 12:48:57   编辑:Linux技術

linux啟動start_kernel之console_init

[code]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比較,如果相符,就

從這個控制台輸出。

Copyright © Linux教程網 All Rights Reserved