内核移植的首要是让内核跑起来,直到引导init进程;为了直观的跟踪内核的启动过程,首先保证打印能正常工作至关重要。
内核打印毫无疑问是调用printk函数,所以需要跟踪printk的执行过程来确定需要移植哪些内容。
printk函数经过一系列的同步保护和log缓冲区的格式化之后,最终调用到实际的底层驱动函数static void _call_console_drivers(unsigned start, unsigned end, int msg_log_level)。从该函数可以看出要使打印输出必须确保两个条件:打印级别够高、系统是否已注册了控制台(组织成单链表,以console_drivers指针指向第一个)。如果在排它模式下只有特定的控制台可以打印,否则只要找到已使能并提供打印方法的控制台就执行打印任务。最终的打印驱动为struct console cons->write()。
注册控制台:void register_console(struct console *newcon)
需要注意的几点:
1、如果系统已经注册了非CON_BOOT控制台,则不能再注册CON_BOOT控制台;
2、注册成功的控制台依次会调用newcon->early_setup()和newcon->setup()进行初始化;
3、当没有选定preferred_console时,第一个注册的控制台则成为preferred_console;
4、selected_console由启动命令行参数console=来指定;此外update_console_cmdline()和add_preferred_console()也可以更新selected_console;
5、启动命令行参数keep_bootcon=指定当有CON_CONSDEV控制台注册时是否卸载CON_BOOT控制台;
启动命令行参数
1、console= 指定selected_console;
2、keep_bootcon= 指定当有CON_CONSDEV控制台注册时是否卸载CON_BOOT控制台;