如何使用printf调试Linux内核的汇编代码 [英] How to debug using printf an assembly code of linux kernel

查看:573
本文介绍了如何使用printf调试Linux内核的汇编代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是我正在尝试的文件通过放置printf/printk语句进行调试.

This is the file that I am trying to debug by putting printf/printk statements.

代码是汇编代码.

 79         __HEAD
 80 ENTRY(stext)
 81  ARM_BE8(setend be )                    @ ensure we are in BE8 mode
 82 
 83  THUMB( adr     r9, BSYM(1f)    )       @ Kernel is always entered in ARM.
 84  THUMB( bx      r9              )       @ If this is a Thumb-2 kernel,
 85  THUMB( .thumb                  )       @ switch to Thumb now.
 86  THUMB(1:                       )
 87 
 88 #ifdef CONFIG_ARM_VIRT_EXT
 89         bl      __hyp_stub_install
 90 #endif
 91         @ ensure svc mode and all interrupts masked
 92         safe_svcmode_maskall r9
 93 
 94         mrc     p15, 0, r9, c0, c0              @ get processor id
 95         bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
 96         movs    r10, r5                         @ invalid processor (r5=0)?
 97  THUMB( it      eq )            @ force fixup-able long branch encoding
 98         beq     __error_p                       @ yes, error 'p'
 99 
100 #ifdef CONFIG_ARM_LPAE
101         mrc     p15, 0, r3, c0, c1, 4           @ read ID_MMFR0
102         and     r3, r3, #0xf                    @ extract VMSA support
103         cmp     r3, #5                          @ long-descriptor translation table format?
104  THUMB( it      lo )                            @ force fixup-able long branch encoding
105         blo     __error_lpae                    @ only classic page table format
106 #endif
107 
108 #ifndef CONFIG_XIP_KERNEL
109         adr     r3,

我只是想从此文件中向控制台添加一些消息.这段代码是针对ARM的.

I simply want to put some messages to console from this file. This code is for ARM.

我尝试在此类代码块中使用printk,但无法编译.

I tried using printk in such code blocks but it fails to compile.

有什么建议吗?

推荐答案

答案在 ARM启动常见问题解答 .您需要启用配置菜单项 Kernel Hacking | Kernel低级调试功能.例如,代码 __error_p 然后会在您的控制台UART上显示一些内容.例如, elinux.org的通过打印进行调试" 显示了内核错误信息无法匹配您的计算机ID. 请参阅: ARM引导文档

The answer is given in ARM booting FAQ. You need to enable the config menu item Kernel Hacking|Kernel low-level debugging functions. For instance, the code __error_p will then display something on your console UART. For instance, elinux.org's Debugging by printing shows an error message when the kernel can not match your machine id. See: ARM booting documentation

DEBUG_LL 创建功能extern void printascii(char *);,您也可以使用它来测试vprintk_emit().

DEBUG_LL creates the function extern void printascii(char *); which you can also instrument vprintk_emit() with.

--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -1483,6 +1483,8 @@ static size_t cont_print_text(char *text, size_t size)
        return textlen;
 }

+extern void printascii(char*);
+
 asmlinkage int vprintk_emit(int facility, int level,
                            const char *dict, size_t dictlen,
                            const char *fmt, va_list args)
@@ -1541,6 +1543,7 @@ asmlinkage int vprintk_emit(int facility, int level,
         * prefix which might be passed-in as a parameter.
         */
        text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
+       printascii(text);

        /* mark and strip a trailing newline */
        if (text_len && text[text_len-1] == '\n') {

这和内核命令行 initcall_debug 对诊断启动问题很有用.

This and the kernel command line initcall_debug will be useful to diagnose boot issue.

如果您的平台不支持 DEBUG_LL ,则很容易实现支持它的轮询UART例程.

If you platform doesn't support the DEBUG_LL, it is fairly easy to implement the polled UART routines needed to support it.

通常,printk()在早期启动期间被缓冲,并且直到控制台驱动程序处于活动状态时才真正打印出来.因此,无需修补vprintk_emit(),您就可以在UART驱动程序运行之前的任何地方崩溃/停止运行,并且在常规配置下看不到任何东西.

Normally, printk() is buffered during early boot and doesn't actually print out until the console driver is active. So, without patching the vprintk_emit(), you can crash/halt anywhere before the UART driver runs and see nothing with a normal configuration.

要调试 head.S 等,您需要在汇编器中执行此操作. error_p实现有一些示例代码,这里是另一个示例代码,

For debugging of head.S and the like, you need to do this in assembler. The error_p implementation has some sample code and here is another,

 #ifdef CONFIG_DEBUG_LL
         /* Save some registers? */
         adr     r0, prefix
         bl      printascii
         mov     r0, r9
         bl      printhex8
         adr     r0, tail
         bl      printascii
         b       1f
 prefix: .asciz  "\nTrace 1 gives "
 tail:   .asciz  "\n"
 1:  /* Perhaps halt here, due to register clobbers */
 #endif

根据 head.S 中的上下文,您只能使用寄存器.通常,此代码的唯一问题是您没有执行

You are limited in the use of registers depending on the context in head.S. Often the only issue with this code is you didn't do something described in the ARM booting documentation.

您也可以直接使用

You may also use the macros directly which are defined in arch/arm/include/debug. The macros are,

  • addruart-将uart的地址设置为参数1(phys),2(virt),(第3个是宏的tmp).
  • senduart-将字符参数1写入地址(虚拟或物理).
  • waituart-参数1(tmp),参数2地址(virt或phys).准备好了吗?
  • busyuart-参数1(tmp),参数2地址(virt或phys).空吗?
  • addruart - get the addresses of the uarts to parameter 1 (phys), 2 (virt), (3rd is a tmp for macro).
  • senduart - write character param 1 to address (virtual or physical).
  • waituart - parm 1 (tmp), param 2 address (virt or phys). Ready?
  • busyuart - parm 1 (tmp), param 2 address (virt or phys). Empty?

您可以在 head.S 和其他程序的汇编程序中,可以将宏与各种寄存器参数一起使用,以避免使用中的寄存器(如r0-r3)的混乱.通常可以使用它们,并且printascii()可以直接调用.

In the assembler of head.S and others, you can use the macros with various register arguments to avoid clobbers of in-use registers such as r0-r3. They are usually available for use and printascii() can be called directly.

这篇关于如何使用printf调试Linux内核的汇编代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆