linux的early printk的探讨
http://mcuos.com/thread-8169-1-1.html
(一)知识背景:
- [color=Red]Uncompressing Linux... done, booting the kernel.
- ------------setup_arch------------
- ------------setup_machine_fdt return 0------------
- Machine: MCUOS6410[/color]
- 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
- bootconsole [earlycon0] enabled
- S3C24XX Clocks, Copyright 2004 Simtec Electronics
- camera: no parent clock specified
- S3C64XX: PLL settings, A=532000000, M=532000000, E=24000000
- S3C64XX: HCLK2=266000000, HCLK=133000000, PCLK=66500000
- mout_apll: source is fout_apll (1), rate is 532000000
- mout_epll: source is epll (1), rate is 24000000
复制代码
我们知道line 5-12行代码部分, 是 printk打印出来的。而如果你想要在打印linux的版本之前的 函数 line1-4行中也加打印信息,那么printk这个时候其实 串口 ,console什么的还没注册呢,所以肯定没有信息的。比如说,我想打印setup函数中的部分 调试 信息:
- void __init setup_arch(char **cmdline_p)
- {
- struct machine_desc *mdesc;
- unwind_init();
- setup_processor();
- early_printk("------------setup_arch------------\n");
- //return ;
- mdesc = setup_machine_fdt(__atags_pointer);
- early_printk("------------setup_machine_fdt return %d------------\n", mdesc);
- if (!mdesc)
- mdesc = setup_machine_tags(machine_arch_type);
- machine_desc = mdesc;
- machine_name = mdesc->name;
- early_printk("Machine: %s\n", machine_name);
- if (mdesc->soft_reboot)
- 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文件,上代码:
- extern void printch(int);
- static void early_write(const char *s, unsigned n)
- {
- while (n-- > 0) {
- if (*s == '\n')
- printch('\r');
- printch(*s);
- s++;
- }
- }
- static void early_console_write(struct console *con, const char *s, unsigned n)
- {
- early_write(s, n);
- }
- static struct console early_console = {
- .name = "earlycon",
- .write = early_console_write,
- .flags = CON_PRINTBUFFER | CON_BOOT,
- .index = -1,
- };
- asmlinkage void early_printk(const char *fmt, ...)
- {
- char buf[512];
- int n;
- va_list ap;
- va_start(ap, fmt);
- n = vscnprintf(buf, sizeof(buf), fmt, ap);
- early_write(buf, n);
- va_end(ap);
- }
- static int __init setup_early_printk(char *buf)
- {
- register_console(&early_console);
- return 0;
- }
- early_param("earlyprintk", setup_early_printk);
复制代码
其实这段code最终的实现都是靠:extern void printch(int);这个函数。这个函数实现是在:
arch/arm/kernel/debug.S中:
- ENTRY(printch)
- addruart_current r3, r1, r2
- mov r1, r0
- mov r0, #0
- b 1b
- ENDPROC(printch)
复制代码
- .macro addruart_current, rx, tmp1, tmp2
- addruart \tmp1, \tmp2
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1
- moveq \rx, \tmp1
- movne \rx, \tmp2
- .endm
复制代码
printch会调用到 addruart_current函数,而addruart_current函数用调用到:addruart函数,该函数实现是在:
arch\arm\mach-s3c64xx\ include \mach中的debug-macro.S汇编文件中:
- .macro addruart, rp, rv
- ldr \rp, = S3C_PA_UART
- ldr \rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
- #if CONFIG_DEBUG_S3C_UART != 0
- add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
- add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
- #endif
- .endm
复制代码
我们从上面的代码可以看到S3C_PA_UART, S3C_PA_UART都是实际的6410的串口 寄存器 物理和虚拟地址,从而进行真正的 硬件 底层操作。
linux的early printk的探讨相关推荐
- [console] early printk实现流程
本文以ARM为例 一.功能说明 printk的log输出是由console实现(会在其他文章中说明).由于在kernel刚启动的过程中,还没有为串口等设备等注册console(在device prob ...
- Linux内核之 printk 打印
Linux内核之 printk 打印 前言 一.printk 介绍 1. printk 消息级别 2.内核 printk 文件 二.调整打印级别 1.在 menuconfig 中修改 2.在系统中修改 ...
- Linux查看dmesg日志,Linux中的Printk与dmesg功能
要将linux内核的带级别控制的printk内容打印出来,在命令行输入 dmesg -n 8 就将所有级别的信息都打印出来. Linux命令:dmesg 功能说明:显示开机信息. 语 法:dmesg ...
- yuzu模拟器linux,Yuzu Early Acces
Yuzu Early Acces是由Citra团队研发的一款Switch开源模拟器,通过c++编写,支持手柄.支持多核运行,有了这款模拟器玩家就可以很好的对switch游戏进行模拟使用,而且软件支持在 ...
- linux内核acpi,从内核模块探讨ACPI与BIOS及OS之关系
首先,标题说是探讨,其实就是一个简单的介绍.其中内核模块呢,是本人自己写的一个纯粹做demo使用的程序,这个模块通过ACPI来获得系统中处理器的信息(数量及ID),当然Linux内核源码中有一个ACP ...
- LINUX 消息队列的容量探讨
在LINUX进程间通信方法有很多种,其中有消息队列.信号量.共享内存,而这三种进程间通信方法又分为System V IPC 和 POSIX IPC 两类. 接下来要探讨的是POSIX的消息对列(实际编 ...
- linux内核中printk的打印级别
内核中预定义的内核log等级 // include/linux/kern_levels.h#define KERN_SOH "\001" /* ASCII Start Of Hea ...
- 修改Linux内核的printk缓冲区(log缓冲区)大小
点击打开链接 我们可以用printk打印kernel的日志信息(即log信息),根据时间戳可以判断内核新打印的log会覆盖掉以前打印的log.原因是内核用环形缓冲区存放打印的log信息.那么如何增大缓 ...
- linux驱动中printk的使用注意事项
今天在按键驱动中增加printk(KERN_INFO "gpio_keys_gpio_isr()\n");在驱动加载阶段可以输出调试信息,但驱动加载起来后的信息,在串口端看不到输出 ...
最新文章
- java生成sql语句_java生成SQL语句
- Json串到json对象的转换
- 使用@Autowired注入RedisTemplate时报java.lang.NullPointerException
- Python常见的数据类型【数字、布尔、字符串、列表和元组、字典】
- Java 自动装箱与拆箱
- 安装openstack时遇到的错误
- 亮点抢先看 | 旷视科技11篇 ICCV 2019 论文概览
- 基于springMVC的页面跳转、转发、重定向等
- Scala安装及环境变量配置
- 电商价格战 谁才是最大受益者
- GD32F103基础教程—教程简介(一)
- 【Office 365 2108更新】
- c语言用函数求组合数编程,C语言函数
-C语言求组合数
- 2B市场行业,面向2025年技术趋势与5大机会,赶快来看一看吧
- 教你win10更新失败怎么解决,win10系统更新失败怎么办
- size(),length和length()的区别(最详细版)
- IE6 IE7 并存
- matlab专业代做hslogic,MATLAB代做|FPGA代做--OLA算法的仿真与分析
- 使用SpringBoot及Construct2的WebSocket制作联机游戏(二)
- Linux 内核/sys 文件系统介绍