kernel初始化调试

最近在调试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 *)可以直接输出。

printascii函数是在arm/kernel/debug.S中定义:

ENTRY(printascii)

addruart r3

b        2f

1:                waituart r2, r3

senduart r1, r3

busyuart r2, r3

teq        r1, #'\n'

moveq        r1, #'\r'

beq        1b

2:               teq         r0, #0

ldrneb        r1, [r0], #1

teqne        r1, #0

bne        1b

mov        pc, lr

 

其中waituart ,busyuart 等宏都是在linux/include/asm-arm/arch-sep0718/debug-macro.S中定义的。

完善了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

Rockie Cheng


附代码修改:kernel/printk.c   <<-

extern void printascii(const char*);    // Modify

static char printk_buf[1024];           // Modify

asmlinkage int printk(const char *fmt, ...)

{

    va_list args;

    int r;

    va_start(args, fmt);

    r = vprintk(fmt, args);

    va_end(args);

    printascii(printk_buf);            // Modify

    return r;

}

static int recursion_bug;

static int new_text_line = 1;

//static char printk_buf[1024];        // Modify



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: sldebug 是一个用于调试 Linux 内核模块的工具。如果它一直卡在初始化阶段,可能是因为它无法正常连接到内核。你可以尝试以下步骤解决这个问题: 1. 确认 sldebug 是否支持你当前使用的内核版本。你可以查看 sldebug 的官方文档或者手册来确认。 2. 确认你的内核配置中是否启用了相关的调试选项,例如 CONFIG_DEBUG_KERNEL 和 CONFIG_KGDB。 3. 检查你的系统是否有足够的权限来访问内核调试接口,例如 /dev/kmem 和 /dev/mem。 4. 尝试重新编译和安装 sldebug。 如果以上步骤都无法解决问题,你可以尝试使用其他的内核调试工具,例如 GDB 或者 SystemTap。 ### 回答2: 当 sldebug 运行后一直处于初始化状态时,可能是因为以下几个原因: 1. 网络连接问题:sldebug 可能需要访问网络资源来进行初始化,如果网络连接不稳定或存在问题,可能会导致初始化过程无法完成。此时,可以尝试检查网络连接是否正常,或者尝试使用其他网络连接来解决问题。 2. 资源加载问题:sldebug 的初始化过程可能依赖于某些资源文件或者配置文件。如果这些文件缺失或者加载失败,就会导致初始化失败。此时,可以检查相关的资源文件是否存在,并确保它们被正确地加载和访问。 3. 硬件要求不满足:sldebug 可能有一些硬件要求,例如硬盘空间、内存大小等。如果你的计算机硬件不满足这些要求,sldebug 可能无法启动或者初始化。在这种情况下,可以尝试升级硬件或者使用更加适合的计算机来运行 sldebug。 4. 软件版本不匹配:sldebug 的初始化过程可能依赖于其他软件或者库的版本。如果这些软件或者库的版本与 sldebug 不兼容,就可能导致初始化失败。在这种情况下,可以尝试升级相关软件或者库的版本,或者使用与 sldebug 兼容的版本。 如果以上方法都无法解决问题,建议向 sldebug 的开发者或者官方技术支持团队寻求帮助,提供详细的错误信息和操作过程,以便他们能够更好地理解和解决问题。 ### 回答3: sldebug是一种调试工具,用于调试软件或应用程序的运行过程。一般来说,当我运行sldebug后,它会立即开始初始化过程。然而,如果sldebug一直在初始化,可能会有几个可能的原因。 首先,可能是因为你的计算机性能较低,无法快速完成初始化过程。这可能是由于计算机硬件过旧或运行过程中存在其他资源密集型任务导致的。此时,你可以尝试关闭其他不必要的程序,以释放资源,或者考虑升级你的计算机硬件。 其次,sldebug可能需要连接到外部服务器或数据库来获取必要的数据。如果服务器或数据库出现问题或连接速度较慢,sldebug的初始化过程可能会受到影响。你可以尝试检查网络连接是否正常,或者尝试连接其他服务器或数据库来解决这个问题。 最后,sldebug自身可能存在BUG或错误,导致初始化过程无法正常完成。在这种情况下,你可以尝试更新或重新安装sldebug,以修复任何潜在的问题。 总之,如果sldebug在运行后一直处于初始化状态,你可以尝试优化计算机性能,检查网络连接,或升级/重新安装sldebug来解决这个问题。如果问题仍然存在,你可以尝试与sldebug的开发者或支持团队联系,以获取进一步的帮助和支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值