1、uboot跳转到内核启动的时候通过环境变量 console设置控制台

(console = ttySAC0表示输出到串口,并从串口结束输入,也可以设置console=tty1,表示输出到LCD,从inputevent接受输入事件)

2、内核用printk打印,printk肯定要调用硬件函数,其通过console参数来确定具体硬件,调用对应的硬件处理函数

  在内核中搜索“console=”,可以看到__setup("console=",console_setup),__setup是个宏

以console为例,在/kernel/printk.c中,如下:

  1. static int __init console_setup(char *str)
  2. {
  3. .......
  4. }
  5. __setup("console=", console_setup);

__setup宏定义展开,如下:

  1. Static struct obs_kernel_param __setup_console_setup
  2. __used_section(.init.setup) __attribute__((aligned((sizeof(long)))) = {
  3. .name = “console=”,
  4. .setup_func = console_setup,
  5. .early = 0
  6. }

__setup_console_setup编译时就会链接到.init.setup段中,kernel运行时就会根据cmdline中的参数名与.init.setup段中obs_kernel_param的name对比。

匹配则调用console-setup来解析该参数,console_setup的参数就是cmdline中console的值

1. 内核处理UBOOT传入的参数
console_setup
  add_preferred_console // 我想用名为"ttySAC0"的控制台,先保存在console_cmdline中,可以有多个console,会在register_console中被使用来比较

2. 硬件驱动的入口函数里:
drivers/serial/s3c2410.c
  register_console(&s3c24xx_serial_console);//注册console,其有个名字,内核会把这个名字和uboot中传过来的被保存的那个名字链表比较,s3c24xx_serial_console结构体有write函数,会被prinkt调用;register_console会把s3c24xx_serial_console放在console_drivers的尾部

(3.4.2的内核如下

drivers/tty/serial/samsung.c

s3c24xx_serial_probe

  uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);//s3c24xx_uart_drv的cons成员就是提供串口写操作的函数

    uart_configure_port

      register_console(port->cons);//同上面其他内核分析的,会把cons保存在console_drivers这个console链表上,其就是个链表头,根据它可以找到多个cons,这里的cons就是上面s3c24xx_uart_drv的cons,在uart_add_one_port中赋的值

3.printk
    vprintk
        /* Emit the output into the temporary buffer */
        // 先把输出信息放入临时BUFFER
        vscnprintf

        // Copy the output into log_buf.
        // 把临时BUFFER里的数据稍作处理,再写入log_buf(处理打印级别,给无打印级别的添加默认打印级别 )
        // 比如printk("abc")会得到"<4>abc", 再写入log_buf
        // 可以用dmesg命令把log_buf里的数据打印出来重现内核的输出信息

        // 调用硬件的write函数输出,3.4.2内核是console_unlock函数
        release_console_sem();或者console_unlock
            call_console_drivers(_con_start, _log_end);
                // 从log_buf得到数据,算出打印级别
                _call_console_drivers(start_print, cur_index, msg_level); //通过drivers的“s”看出可以打印到多个设备,在uboot环境变量中设置多个console=
                    // 如果可以级别够格打印
                    if ((msg_log_level < console_loglevel
                          __call_console_drivers
                              con->write(con, &LOG_BUF(start), end - start);

cat  /proc/sys/kernel/printk

7  4  1  7

console_loglevel  default_message_loglevel  minimum_console_loglevel  defaule_console_loglevel

通过“echo  "8 4 1 7"  >  /proc/sys/kernel/printk”来设置

内核文档kernel-parameters.txt有介绍这些环境变量参数,可以设置loglevel=这些环境变量,在uboot的环境变量中设置

最新文章

  1. 采用cocos2d-x lua 制作数字滚动效果样例
  2. DataList无数据如何显示
  3. 其实Unix很简单
  4. 一SERVLET (1)
  5. Github上LeakCanary编译报错CreateProcess error=2的解决方法
  6. Maven —— 如何设置HTTP代理
  7. TeeChart的X轴,使用伪装的时间
  8. android webview js alert对话框 不能弹出 解决办法
  9. angular2 学习笔记 ( DI 依赖注入 )
  10. emacs window版环境配置(设置默认的.emacs文件,指向自定义.emacs达到自定义home的目的)
  11. HBase加Solr
  12. Linux Shell脚本入门--awk命令详解
  13. 读书笔记—CLR via C#章节8-10
  14. 【java】实现一个简单的正则:判断一个字符串是否全由数字组成
  15. uboot的启动过程-FDT
  16. Java第二次作业程序设计作业
  17. 通过 CLI 管理 Jenkins Server
  18. [Unity算法]斜抛运动
  19. 转--O2O刷单“黑市”折射下的泡沫#神作#
  20. 【Unity笔记】使用协程(Coroutine)异步加载场景

热门文章

  1. java使double保留两位小数的多方法
  2. Checkpoint &amp; cache &amp; persist
  3. 顶级、块级、内联,html元素的三大分类
  4. gdal读写图像分块处理
  5. ios学习之旅---c语言函数
  6. UVA - 10167 - Birthday Cake (简单枚举)
  7. 自己定义控件的onMeasure方法具体解释
  8. 请求不携带cookie问题
  9. Appium_pytest fixture的使用
  10. CentOS 6 IPv6 关闭方法