慢慢欣赏linux 使用qemu调试startup_64

7 篇文章 0 订阅
1 篇文章 0 订阅

很多文章写调试qemu都是从start_kernel开始的,那么start_kernel之前的函数如何调试呢。尤其是 startup_64
即使打上了断点也无法跟踪。
原因是 startup_64 在 vmlinux 里面对应的是链接地址。

7262499 ffffffff81000000 <_text>:
7262500 ffffffff81000000:       48 8d 2d f9 ff ff ff    lea    -0x7(%rip),%rbp        # ffffffff81000000 <_text>

而实际上 startup_64 执行的时候, 页表还没有建立, 使用的虚拟地址跟物理地址是1:1对应的, 也就是其执行的时候, 虚拟地址和物理地址是相等的。
那么怎么找到其开始运行的时候的物理地址呢?

rlk@ubuntu:runninglinuxkernel_4.0_x86$ cat .config | grep CONFIG_RELOCATABLE
CONFIG_RELOCATABLE=y

rlk@ubuntu:runninglinuxkernel_4.0_x86$ cat .config | grep CONFIG_PHYSICAL_START
CONFIG_PHYSICAL_START=0x1000000
rlk@ubuntu:runninglinuxkernel_4.0_x86$ 

rlk@ubuntu:kernel$ vi vmlinux.lds
SECTIONS
{
         . = (0xffffffff80000000 + ALIGN(0x1000000, 0x200000));
         phys_startup_64 = startup_64 - 0xffffffff80000000;

}

调试代码对应的汇编语言如下

 7262497 Disassembly of section .text:
 7262498 
 7262499 ffffffff81000000 <_text>:
 7262500 ffffffff81000000:       48 8d 2d f9 ff ff ff    lea    -0x7(%rip),%rbp        # ffffffff81000000 <_text>
 7262501 ffffffff81000007:       48 81 ed 00 00 00 01    sub    $0x1000000,%rbp
 7262502 ffffffff8100000e:       48 89 e8                mov    %rbp,%rax
 7262503 ffffffff81000011:       25 ff ff 1f 00          and    $0x1fffff,%eax
 7262504 ffffffff81000016:       85 c0                   test   %eax,%eax
 7262505 ffffffff81000018:       0f 85 a7 01 00 00       jne    ffffffff810001c5 <bad_address>
 7262506 ffffffff8100001e:       48 8d 05 db ff ff ff    lea    -0x25(%rip),%rax        # ffffffff81000000 <_text>
 7262507 ffffffff81000025:       48 c1 e8 2e             shr    $0x2e,%rax
 7262508 ffffffff81000029:       0f 85 96 01 00 00       jne    ffffffff810001c5 <bad_address>
 7262509 ffffffff8100002f:       48 01 2d c2 7f f4 00    add    %rbp,0xf47fc2(%rip)        # ffffffff81f47ff8 <early_level4_pgt+0xff8>
 7262510 ffffffff81000036:       48 01 2d b3 ff e0 00    add    %rbp,0xe0ffb3(%rip)        # ffffffff81e0fff0 <level3_kernel_pgt+0xff0>
 7262511 ffffffff8100003d:       48 01 2d b4 ff e0 00    add    %rbp,0xe0ffb4(%rip)        # ffffffff81e0fff8 <level3_kernel_pgt+0xff8>
 7262512 ffffffff81000044:       48 01 2d 85 1f e1 00    add    %rbp,0xe11f85(%rip)        # ffffffff81e11fd0 <level2_fixmap_pgt+0xfd0>
 7262513 ffffffff8100004b:       48 8d 3d ae ff ff ff    lea    -0x52(%rip),%rdi        # ffffffff81000000 <_text>

所以打断点要基于物理地址打断点:

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x000000000000fff0 in scsi_format_log ()
(gdb) b *0x1000000	// 其中, 0x1000000 是 startup_64 运行时的虚拟地址。给地址打断点, 前面需要加上 *
Breakpoint 1 at 0x1000000
(gdb) c
Continuing.

Breakpoint 1, 0x0000000001000000 in ?? ()

(gdb) info reg	// 打印寄存器
rax            0x1000000        16777216
rbx            0x1f19000        32608256
rcx            0x780    1920
rdx            0x3d5    981
rsi            0x140a0  82080
rdi            0x3d5    981
rbp            0x1000000        0x1000000
rsp            0x23fa540        0x23fa540
r8             0x4e1580 5117312
r9             0x14d9000        21860352
r10            0xd      13
r11            0xa      10
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0x1000000        0x1000000
eflags         0x2      [ IOPL=0 ]
cs             0x10     16
ss             0x0      0
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
fs_base        0x0      0
gs_base        0x0      0
k_gs_base      0x0      0
cr0            0x80000011       [ PG ET PE ]
cr2            0x0      0
cr3            0x23fb000        [ PDBR=1 PCID=0 ]
cr4            0x20     [ PAE ]
cr8            0x0      0
efer           0x500    [ LMA LME ]
mxcsr          0x1f80   [ IM DM ZM OM UM PM ]

(gdb) n       
Cannot find bounds of current function
(gdb) s
Cannot find bounds of current function

(gdb) b *0x1000007
Breakpoint 2 at 0x1000007

(gdb) c
Continuing.

Breakpoint 2, 0x0000000001000007 in ?? ()
(gdb) info reg
rax            0x1000000        16777216
rbx            0x1f19000        32608256
rcx            0x780    1920
rdx            0x3d5    981
rsi            0x140a0  82080
rdi            0x3d5    981
rbp            0x1000000        0x1000000
rsp            0x23fa540        0x23fa540
r8             0x4e1580 5117312
r9             0x14d9000        21860352
r10            0xd      13
r11            0xa      10
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0x1000007        0x1000007
eflags         0x2      [ IOPL=0 ]
cs             0x10     16
ss             0x0      0
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
fs_base        0x0      0
gs_base        0x0      0
k_gs_base      0x0      0

(gdb) b *0x100001e
Breakpoint 3 at 0x100001e

(gdb) c
Continuing.

Breakpoint 3, 0x000000000100001e in ?? ()
(gdb) info reg
rax            0x0      0	// 这条语句讲rax清零 ffffffff81000011:       25 ff ff 1f 00          and    $0x1fffff,%eax
rbx            0x1f19000        32608256
rcx            0x780    1920
rdx            0x3d5    981
rsi            0x140a0  82080
rdi            0x3d5    981
rbp            0x0      0x0 <irq_stack_union>
rsp            0x23fa540        0x23fa540
r8             0x4e1580 5117312
r9             0x14d9000        21860352
r10            0xd      13
r11            0xa      10
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0x100001e        0x100001e
eflags         0x46     [ IOPL=0 ZF PF ]
cs             0x10     16
ss             0x0      0
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
fs_base        0x0      0
gs_base        0x0      0
k_gs_base      0x0      0
cr0            0x80000011       [ PG ET PE ]
cr2            0x0      0
cr3            0x23fb000        [ PDBR=1 PCID=0 ]
cr4            0x20     [ PAE ]
cr8            0x0      0
efer           0x500    [ LMA LME ]

(gdb) b *0x1000025
Breakpoint 4 at 0x1000025

(gdb) c       
Continuing.

Breakpoint 4, 0x0000000001000025 in ?? ()

(gdb) info reg
rax            0x1000000        16777216	// ffffffff8100001e:       48 8d 05 db ff ff ff    lea    -0x25(%rip),%rax        # ffffffff81000000 <_text>
rbx            0x1f19000        32608256
rcx            0x780    1920
rdx            0x3d5    981
rsi            0x140a0  82080
rdi            0x3d5    981
rbp            0x0      0x0 <irq_stack_union>
rsp            0x23fa540        0x23fa540
r8             0x4e1580 5117312
r9             0x14d9000        21860352
r10            0xd      13
r11            0xa      10
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0x1000025        0x1000025
eflags         0x46     [ IOPL=0 ZF PF ]

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值