最近在调试Linux内核,跟踪启动过程。发现在没有turn on mmu之前,可以使用物理地址,通过向串口Fifo丢数据的方式输出调试信息。但是代码一旦运行到开启mmu,在汇编阶段,mmu只做了物理内存的映射,并没有映射io,所以就无法访问串口了。
 
此时应该通过串口输出的数据都保存在串口缓冲池里,直到在c语言阶段,建立io映射并初始化控制台后才进行输出。
 
但是,如果我想实时跟踪内核启动过程,应该如何才好?
这是就要提到Linux的Lowlevel Debug功能了。
 
这个选项位于:
Kernel hacking  ---> 
 [*] Kernel debugging 
 [*] Kernel low-level debugging functions 
 
打开这个选项会在.config中增加CONFIG_DEBUG_LL宏定义
初步估计,影响的地方有以下几点:
(1)arch/arm/kernel/head.s的__create_page_tables部分
(2)arch/arc/mach-处理器/处理器.c中的宏定义部分
(3)kernel/prink.c
为了提供DEBUG_LL功能,还必须完善arch/arc/mach-处理器/include/mach/debug-macro.S
 
首先说说好处,为什幺打开Kernel low-level debugging functions 功能。
打开这个宏定义后,会在head.s函数的__create_page_tables建立一部分io映射,具体代码如下:
 
#ifdef CONFIG_DEBUG_LL
ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
/*
 * Map in IO space for serial debugging.
 * This allows debug messages to be output
 * via a serial console before paging_init.
 */
ldr r3, [r8, #MACHINFO_PGOFFIO]
add r0, r4, r3
rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
cmp r3, #0x0800 @ limit to 512MB
movhi r3, #0x0800
add r6, r0, r3
ldr r3, [r8, #MACHINFO_PHYSIO]
orr r3, r3, r7
1: str r3, [r0], #4
add r3, r3, #1 << 20
teq r0, r6
bne 1b
 
代码中也提到,映射io的作用是为了串口调试使用。
这段代码中使用的物理地址和虚拟地址从何而来?arch/arc/mach-处理器/处理器.c中的宏定义部分
比如以下处理器:
MACHINE_START(EASIC0718, "SEP0718 board")
 
.phys_io = 0x10005000,
.io_pg_offst = ((0xe005000) >> 18) & 0xfffc,
.boot_params = 0x30000100,
.fixup = fixup_gfd0718,
.map_io = sep0718_map_io,
.init_irq =  sep0718_init_irq,
.init_machine = sep0718_init,
.timer = &sep0718_timer,
 
MACHINE_END
 
中间
.phys_io = 0x10005000,
.io_pg_offst = ((0xe005000) >> 18) & 0xfffc,
就是供__create_page_tables的 CONFIG_DEBUG_LL中做io映射使用
 
最后就是对printk.c的改动了,主要是多定义了void printascii(char *)可以直接输出。
完善了debug-macro.S后可以用printascii了。建立了内存映射后,哪里都可以用,无论汇编还是C,无论开mmu前还是开mmu后。代码会判断有没有开mmu的。
同时prink会在缓冲池保留一份数据,也同时调用printkasii直接输出,因此内核启动后会看到信息输出了两次。
 
最后贴上debug-macro.S,writed by leeming,注意其中的io地址和处理器架构相关,不能直接使用。
/* linux/include/asm-arm/arch-sep0718/debug-macro.S
 *
 * Debugging macro include header
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
*/
#include <asm/hardware.h>
 
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
moveq \rx, #0x10000000
movne \rx, #0xe0000000
add  \rx, \rx, #0x5000
.endm
 
.macro senduart,rd,rx
str \rd, [\rx] @ UARTDR
.endm
            
.macro waituart,rd,rx
1001: ldr \rd, [\rx, #0x14] @ SYSFLGx
tst \rd, #1 << 6 @ UBUSYx
beq 1001b
.endm
 
.macro busyuart,rd,rx
1001: ldr \rd, [\rx, #0x14] @ SYSFLGx
tst \rd, #1 << 6 @ UBUSYx
beq 1001b
.endm

跟踪内核启动过程CONFIG_DEBUG_LL【转自】的更多相关文章

  1. Linux内核启动过程概述

    版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...

  2. Linux移植之内核启动过程start_kernel函数简析

    在Linux移植之内核启动过程引导阶段分析中从arch/arm/kernel/head.S开始分析,最后分析到课start_kernel这个C函数,下面就简单分析下这个函数,因为涉及到Linux的内容 ...

  3. Linux移植之内核启动过程引导阶段分析

    在Linux移植之make uImage编译过程分析中已经提到了uImage是一个压缩的包并且内含压缩程序,可以进行自解压.自解压完成之后内核代码从物理地址为0x30008000处开始运行.下面分析在 ...

  4. linux内核启动过程

    作者:严哲璟 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 通过qemu以 ...

  5. 1.移植3.4内核-分析内核启动过程,重新分区,烧写jffs2文件系统

    1.在上章-移植uboot里.我们来分析下uboot是如何进入到内核的 首先,uboot启动内核是通过bootcmd命令行实现的,在我们之前移植的bootcmd命令行如下所示: bootcmd=nan ...

  6. 使用gdb跟踪Linux内核启动过程(从start_kernel到init进程启动)

    本次实验过程如下: 1. 运行MenuOS系统 在实验楼的虚拟机环境里,打击打开shell,使用下面的命令 cd LinuxKernel/ qemu -kernel linux-/arch/x86/b ...

  7. 基于linux2.6.38.8内核启动过程完全解析[一]

    转载: ************************************************************************************************ ...

  8. Linux内核启动过程start_kernel分析

    虽然题目是start_kernel分析,但是由于我在ubuntu环境下配置实验环境遇到了一些问题,我觉得有必要把这些问题及其解决办法写下来. 首先我使用的是Ubuntu14.04 amx64,以下的步 ...

  9. Linux内核分析 实验三:跟踪分析Linux内核的启动过程

    贺邦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一. 实验过程 ...

随机推荐

  1. 在a标签的href用户#name 的可以实现页面 上下跳转

  2. 【bzoj4229】选择 离线+LCT

    题目描述 现在,我想知道自己是否还有选择. 给定n个点m条边的无向图以及顺序发生的q个事件. 每个事件都属于下面两种之一: 1.删除某一条图上仍存在的边 2.询问是否存在两条边不相交的路径可以从点u出 ...

  3. Codeforces Round #522 Div. 1 没打记

    开场被A劝退,写了得有50min于是不敢交了.unrated了喜闻乐见. A:瞎猜都能猜到如果要走到那条直线上,进入直线的点横坐标或纵坐标与起点相同,离开直线的点横坐标或纵坐标与终点相同,证明脑补一下 ...

  4. Python文件传输模块ftplib

    ftplib是基于FTP协议实现的一个Python模块 from ftplib import FTP # 创建一个FTP连接对象 ftp = FTP() #[ 当带有参数时,即:ftp = FTP(h ...

  5. JS变量对象详解

    JS变量对象详解 开年之后工作热情一直不是很高,这几天一直处于消极怠工状态.早上不想起床,起床了不想上班.明明放假之前工作热情还一直很高,一直心心念念的想把小程序项目怼出来,结果休假回来之后画风完全不 ...

  6. Javascript 中 == 和 === 区别是什么?

    Javascript 中 == 和 === 区别是什么? 作者:Belleve链接:https://www.zhihu.com/question/31442029/answer/77772323来源: ...

  7. [洛谷P4822][BJWC2012]冻结

    题目大意:有一张$n(n\leqslant50)$个点$m(m\leqslant1000)$条边的无向图,可以使得$k$条边使得边权减半,求最短路 题解:分层图最短路 卡点:无 C++ Code: # ...

  8. bzoj 3132: 上帝造题的七分钟 (二维树状数组)

    推推公式,最后变成四个东西的前缀和 然后不知道为什么一直wa,数据在本地测是没有错的& 好心的管理员还给了某位p党大神a了的代码,感人肺腑(虽然还是没发现到底我的程序是问题) var f1,f ...

  9. BZOJ1509 & 洛谷4408:[NOI2003]逃学的小孩——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1509 https://www.luogu.org/problemnew/show/P4408 sb ...

  10. 爆款PHP面试题

    $a = 3; $b = 6; if ($a = 4 || $b = 4) { $a++; $b++; } echo $a; //输出 1 echo $b; //输出 7 逛鸟哥博客,看评论区有个新手 ...