http://mcuos.com/thread-8169-1-1.html

(一)知识背景:

  1. [color=Red]Uncompressing Linux... done, booting the kernel.
  2. ------------setup_arch------------
  3. ------------setup_machine_fdt return 0------------
  4. Machine: MCUOS6410[/color]
  5. Linux version 3.0.30-g4e794c6-dirty (zswan@zswan-laptop-ubuntu) (gcc version 4.2.1) #17 Sun May 6 00:55:44 CST 2012
  6. bootconsole [earlycon0] enabled
  7. S3C24XX Clocks, Copyright 2004 Simtec Electronics
  8. camera: no parent clock specified
  9. S3C64XX: PLL settings, A=532000000, M=532000000, E=24000000
  10. S3C64XX: HCLK2=266000000, HCLK=133000000, PCLK=66500000
  11. mout_apll: source is fout_apll (1), rate is 532000000
  12. mout_epll: source is epll (1), rate is 24000000

复制代码

我们知道line 5-12行代码部分, 是 printk打印出来的。而如果你想要在打印linux的版本之前的 函数 line1-4行中也加打印信息,那么printk这个时候其实 串口 ,console什么的还没注册呢,所以肯定没有信息的。比如说,我想打印setup函数中的部分 调试 信息:

  1. void __init setup_arch(char **cmdline_p)
  2. {
  3. struct machine_desc *mdesc;
  4. unwind_init();
  5. setup_processor();
  6. early_printk("------------setup_arch------------\n");
  7. //return ;
  8. mdesc = setup_machine_fdt(__atags_pointer);
  9. early_printk("------------setup_machine_fdt return %d------------\n", mdesc);
  10. if (!mdesc)
  11. mdesc = setup_machine_tags(machine_arch_type);
  12. machine_desc = mdesc;
  13. machine_name = mdesc->name;
  14. early_printk("Machine: %s\n", machine_name);
  15. if (mdesc->soft_reboot)
  16. reboot_setup("s");

复制代码

就可以使用early printk的功能啦,那么 如何 打开这个功能呢,下面我做个介绍:
(二)支持early printk对内核需要做的配置
(1)Kernel hacking  ---> Kernel low-level debugging functions -->   Early printk 
(2)boot option中你需要添加 earlyprintk项。类似于:
root=/dev/ram0 console=ttySAC0,115200n8 rdinit=/sbin/init earlyprintk

(三)在需要加打印信息的地方使用early_printk函数代替printk函数。
(四)对early printk的驱动实现的分析

arch/arm/kernel/early_printk.c文件,上代码:

  1. extern void printch(int);
  2. static void early_write(const char *s, unsigned n)
  3. {
  4. while (n-- > 0) {
  5. if (*s == '\n')
  6. printch('\r');
  7. printch(*s);
  8. s++;
  9. }
  10. }
  11. static void early_console_write(struct console *con, const char *s, unsigned n)
  12. {
  13. early_write(s, n);
  14. }
  15. static struct console early_console = {
  16. .name =                "earlycon",
  17. .write =        early_console_write,
  18. .flags =        CON_PRINTBUFFER | CON_BOOT,
  19. .index =        -1,
  20. };
  21. asmlinkage void early_printk(const char *fmt, ...)
  22. {
  23. char buf[512];
  24. int n;
  25. va_list ap;
  26. va_start(ap, fmt);
  27. n = vscnprintf(buf, sizeof(buf), fmt, ap);
  28. early_write(buf, n);
  29. va_end(ap);
  30. }
  31. static int __init setup_early_printk(char *buf)
  32. {
  33. register_console(&early_console);
  34. return 0;
  35. }
  36. early_param("earlyprintk", setup_early_printk);

复制代码

其实这段code最终的实现都是靠:extern void printch(int);这个函数。这个函数实现是在:

arch/arm/kernel/debug.S中:

  1. ENTRY(printch)
  2. addruart_current r3, r1, r2
  3. mov        r1, r0
  4. mov        r0, #0
  5. b        1b
  6. ENDPROC(printch)

复制代码

  1. .macro        addruart_current, rx, tmp1, tmp2
  2. addruart        \tmp1, \tmp2
  3. mrc                p15, 0, \rx, c1, c0
  4. tst                \rx, #1
  5. moveq                \rx, \tmp1
  6. movne                \rx, \tmp2
  7. .endm

复制代码

printch会调用到 addruart_current函数,而addruart_current函数用调用到:addruart函数,该函数实现是在:
arch\arm\mach-s3c64xx\ include \mach中的debug-macro.S汇编文件中:

  1. .macro addruart, rp, rv
  2. ldr        \rp, = S3C_PA_UART
  3. ldr        \rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
  4. #if CONFIG_DEBUG_S3C_UART != 0
  5. add        \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
  6. add        \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
  7. #endif
  8. .endm

复制代码

我们从上面的代码可以看到S3C_PA_UART, S3C_PA_UART都是实际的6410的串口 寄存器 物理和虚拟地址,从而进行真正的 硬件 底层操作。

linux的early printk的探讨相关推荐

  1. [console] early printk实现流程

    本文以ARM为例 一.功能说明 printk的log输出是由console实现(会在其他文章中说明).由于在kernel刚启动的过程中,还没有为串口等设备等注册console(在device prob ...

  2. Linux内核之 printk 打印

    Linux内核之 printk 打印 前言 一.printk 介绍 1. printk 消息级别 2.内核 printk 文件 二.调整打印级别 1.在 menuconfig 中修改 2.在系统中修改 ...

  3. Linux查看dmesg日志,Linux中的Printk与dmesg功能

    要将linux内核的带级别控制的printk内容打印出来,在命令行输入 dmesg -n 8 就将所有级别的信息都打印出来. Linux命令:dmesg 功能说明:显示开机信息. 语 法:dmesg ...

  4. yuzu模拟器linux,Yuzu Early Acces

    Yuzu Early Acces是由Citra团队研发的一款Switch开源模拟器,通过c++编写,支持手柄.支持多核运行,有了这款模拟器玩家就可以很好的对switch游戏进行模拟使用,而且软件支持在 ...

  5. linux内核acpi,从内核模块探讨ACPI与BIOS及OS之关系

    首先,标题说是探讨,其实就是一个简单的介绍.其中内核模块呢,是本人自己写的一个纯粹做demo使用的程序,这个模块通过ACPI来获得系统中处理器的信息(数量及ID),当然Linux内核源码中有一个ACP ...

  6. LINUX 消息队列的容量探讨

    在LINUX进程间通信方法有很多种,其中有消息队列.信号量.共享内存,而这三种进程间通信方法又分为System V IPC 和 POSIX IPC 两类. 接下来要探讨的是POSIX的消息对列(实际编 ...

  7. linux内核中printk的打印级别

    内核中预定义的内核log等级 // include/linux/kern_levels.h#define KERN_SOH "\001" /* ASCII Start Of Hea ...

  8. 修改Linux内核的printk缓冲区(log缓冲区)大小

    点击打开链接 我们可以用printk打印kernel的日志信息(即log信息),根据时间戳可以判断内核新打印的log会覆盖掉以前打印的log.原因是内核用环形缓冲区存放打印的log信息.那么如何增大缓 ...

  9. linux驱动中printk的使用注意事项

    今天在按键驱动中增加printk(KERN_INFO "gpio_keys_gpio_isr()\n");在驱动加载阶段可以输出调试信息,但驱动加载起来后的信息,在串口端看不到输出 ...

最新文章

  1. java生成sql语句_java生成SQL语句
  2. Json串到json对象的转换
  3. 使用@Autowired注入RedisTemplate时报java.lang.NullPointerException
  4. Python常见的数据类型【数字、布尔、字符串、列表和元组、字典】
  5. Java 自动装箱与拆箱
  6. 安装openstack时遇到的错误
  7. 亮点抢先看 | 旷视科技11篇 ICCV 2019 论文概览
  8. 基于springMVC的页面跳转、转发、重定向等
  9. Scala安装及环境变量配置
  10. 电商价格战 谁才是最大受益者
  11. GD32F103基础教程—教程简介(一)
  12. 【Office 365 2108更新】
  13. c语言用函数求组合数编程,C语言函数 -C语言求组合数
  14. 2B市场行业,面向2025年技术趋势与5大机会,赶快来看一看吧
  15. 教你win10更新失败怎么解决,win10系统更新失败怎么办
  16. size(),length和length()的区别(最详细版)
  17. IE6 IE7 并存
  18. matlab专业代做hslogic,MATLAB代做|FPGA代做--OLA算法的仿真与分析
  19. 使用SpringBoot及Construct2的WebSocket制作联机游戏(二)
  20. Linux 内核/sys 文件系统介绍

热门文章

  1. vue自定义日历小组件
  2. android触屏压力方案,如何捕捉压力和面积超过触摸屏android
  3. 国内有哪些VPS值得推荐?
  4. 1行Python代码识别身份证信息,还能自动告警,YYDS
  5. 云海轻站常见问题整理
  6. 基于 Sodor 的矩阵乘法加速器设计之C++
  7. html 标签对应的英文
  8. JS Uncaught TypeError: xxx is not a constructor 问题解析
  9. 面试题错题解析5_操作系统
  10. kali2.0安装flash插件