美文网首页
[OS64][027]源码调试:程序4-11 调试过程 objd

[OS64][027]源码调试:程序4-11 调试过程 objd

作者: AkuRinbu | 来源:发表于2019-06-19 14:29 被阅读0次

    [OS64][025]源码阅读:程序4-11:运行结果,数据结构,第一个进程init_task_union

    https://www.jianshu.com/p/b30fb97a1dc4

    [OS64][026]源码阅读:程序4-11 程序执行过程示意图

    https://www.jianshu.com/p/9bcc6d573978

    程序4-11 调试过程

    • 反汇编源码 objdump -D system
    [anno@localhost kernel]$ objdump -D system > system.txt
    
    • 使用标号名/函数名快速锁定汇编源码,将其与C源码进行对应,从system.txt文件读取线性地址,将其转换成物理地址,就可以在bochs虚拟机里设置断点b 物理地址进行调试
      switch_to.PNG

    一、在什么时候寄存器RSP的值被设置成了第一个进程的栈基地址

    • 第一个进程的栈空间,本质来源于全局变量联合体init_task_union其中的数组字段,这个全局变量位于整个内核的.data.init_task段内
    • 这里可以看到标号_stack_start处就是 就是数值 第一个进程栈空间栈基地址处
    ENTRY(_stack_start)
        .quad   init_task_union + 32768
    
    • 在源码文件 head.S可以看到代码的布局,其中movq _stack_start(%rip), %rsp设置寄存器的RSP值成了第一个进程的栈空间的基地址
    #include "linkage.h"
    
    .section .text
    ENTRY(_start)
    . . .
        mov $0x7E00,    %esp
    
    //=======   load GDTR
    //=======   load    IDTR
    //=======   load    cr3
    //=======   64-bit mode code
    
    switch_seg:
        .quad   entry64
    
    entry64:
    . . .
        movq    _stack_start(%rip), %rsp        
        /* rsp address */
    
    setup_IDT:                          
    . . .
    
    rp_sidt:
    . . .
    
    setup_TSS64:
    . . .
    
    go_to_kernel:
        .quad   Start_Kernel
    
    
    • 在反汇编文件里可以查出语句所在的线性地址0xffff800000100065
    ffff800000100052 <entry64>:
    
    ffff800000100065:   48 8b 25 49 01 00 00    mov    0x149(%rip),%rsp        # ffff8000001001b5 <_stack_start>
    
    • 设置断点 ,查看运行前后的RSP,发现从0x7E00变成了0x120000
    <bochs:8> b 0x100065
    <bochs:9> c
    (0) Breakpoint 3, 0xffff800000100065 in ?? ()
    Next at t=59413777
    (0) [0x000000100065] 0008:ffff800000100065 
    (unk. ctxt): mov rsp, qword ptr ds:[rip+329] ; 488b2549010000
    
    <bochs:10> info cpu
    CPU0:
    rsp: 00000000_00007e00
    
    <bochs:11> s
    
    <bochs:12> info cpu
    CPU0:
    rsp: ffff8000_00120000
    
    

    二、何时才将寄存器RSP的值设置成第二个进程的栈基地址

    • 刚进入switch_to(宏)的时候,寄存器RSP的值是rsp: ffff8000_0011ff58
    <bochs:7> info cpu
    CPU0:
    rax: ffff8000_00118000 rcx: 00000000_00000000
    rdx: ffff8000_00200000 rbx: ffff8000_0010d700
    rsp: ffff8000_0011ff58 rbp: ffff8000_0011ffa8
    rsi: ffff8000_00200000 rdi: ffff8000_00118000
    r8 : 00000000_00ffffff r9 : 00000000_00000000
    r10: ffff8000_00007c00 r11: ffff8000_00007c00
    r12: ffff8000_00200058 r13: ffff8000_00200058
    r14: ffff8000_0010d700 r15: 00000000_00000000
    rip: ffff8000_0010b5b2
    
    
    • 执行完 movq %2, %%rsp之后,寄存器的RSP存入第二个进程的RSP0,成为rsp: ffff8000_00207f40
    <bochs:10> s
    Next at t=62987240
    (0) [0x00000010b5b8] 0008:ffff80000010b5b8 
    (unk. ctxt): mov rsp, qword ptr ds:[r12+16] ; 498b642410
    
    <bochs:11> s
    Next at t=62987241
    (0) [0x00000010b5bd] 0008:ffff80000010b5bd 
    (unk. ctxt): lea rax, qword ptr ds:[rip+13] ; 488d050d000000
    
    <bochs:12> info cpu
    CPU0:
    rax: ffff8000_00118000 rcx: 00000000_00000000
    rdx: ffff8000_00200000 rbx: ffff8000_0010d700
    rsp: ffff8000_00207f40 rbp: ffff8000_0011ffa8
    rsi: ffff8000_00200000 rdi: ffff8000_00118000
    r8 : 00000000_00ffffff r9 : 00000000_00000000
    r10: ffff8000_00007c00 r11: ffff8000_00007c00
    r12: ffff8000_00200058 r13: ffff8000_00200058
    r14: ffff8000_0010d700 r15: 00000000_00000000
    rip: ffff8000_0010b5bd
    
    
    • 执行完pushq %3
    <bochs:14> s
    Next at t=62987243
    (0) [0x00000010b5c8] 0008:ffff80000010b5c8 
    (unk. ctxt): push qword ptr ds:[r13+8] ; 41ff7508
    
    <bochs:15> info cpu
    CPU0:
    rax: ffff8000_0010b5d1 rcx: 00000000_00000000
    rdx: ffff8000_00200000 rbx: ffff8000_0010d700
    rsp: ffff8000_00207f40 rbp: ffff8000_0011ffa8
    rsi: ffff8000_00200000 rdi: ffff8000_00118000
    r8 : 00000000_00ffffff r9 : 00000000_00000000
    r10: ffff8000_00007c00 r11: ffff8000_00007c00
    r12: ffff8000_00200058 r13: ffff8000_00200058
    r14: ffff8000_0010d700 r15: 00000000_00000000
    rip: ffff8000_0010b5c8
    
    
    <bochs:16> s
    Next at t=62987244
    (0) [0x00000010b5cc] 0008:ffff80000010b5cc (unk. ctxt): jmp .-1138 (0xffff80000010b15f) ; e98efbffff
    
    <bochs:17> info cpu
    CPU0:
    rax: ffff8000_0010b5d1 rcx: 00000000_00000000
    rdx: ffff8000_00200000 rbx: ffff8000_0010d700
    rsp: ffff8000_00207f38 rbp: ffff8000_0011ffa8
    rsi: ffff8000_00200000 rdi: ffff8000_00118000
    r8 : 00000000_00ffffff r9 : 00000000_00000000
    r10: ffff8000_00007c00 r11: ffff8000_00007c00
    r12: ffff8000_00200058 r13: ffff8000_00200058
    r14: ffff8000_0010d700 r15: 00000000_00000000
    rip: ffff8000_0010b5cc
    
    
    • 查看当前的栈内容,栈顶[0xffff8000:0x0010b06b]
    <bochs:18> print-stack
    Stack address size 8
     | STACK 0xffff800000207f38 [0xffff8000:0x0010b06b]
     | STACK 0xffff800000207f40 [0x00000000:0x00000000]
     | STACK 0xffff800000207f48 [0x00000000:0x00000000]
     | STACK 0xffff800000207f50 [0x00000000:0x00000000]
    . . . 
    
    • [0xffff8000:0x0010b06b]kernel_thread_func的入口地址,这就是为什么函数__switch_to执行完后会跳转到kernel_thread_func执行的原因
    ffff80000010b06b <kernel_thread_func>:
    ffff80000010b06b:   41 5f                   pop    %r15
    ffff80000010b06d:   41 5e                   pop    %r14
    . . .
    
    • 直接设置断点到函数__switch_toretq处,可见当前处于内核代码段cs:0x0008 Code segment,而retq指令可以视为等价于IP=0x0010b06b(kernel_thread_func)
    <bochs:19> b 0x10b2ed
    <bochs:20> c
    
    (0) Breakpoint 3, 0xffff80000010b2ed in ?? ()
    Next at t=63156040
    (0) [0x00000010b2ed] 0008:ffff80000010b2ed (unk. ctxt): ret                       ; c3
    
    <bochs:22> sreg
    cs:0x0008, dh=0x00209900, dl=0x00000000, valid=1
        Code segment, base=0x00000000, limit=0x00000000, Execute-Only, Non-Conforming, Accessed, 64-bit
    ss:0x0010, dh=0x00009300, dl=0x00000000, valid=1
        Data segment, base=0x00000000, limit=0x00000000, Read/Write, Accessed
    
    
    • 接着进行单步执行,就进入了函数10b06b <kernel_thread_func>,当前rip的数值就可以验证这一点
    <bochs:23> s
    Next at t=63156041
    (0) [0x00000010b06b] 0008:ffff80000010b06b 
    (unk. ctxt): pop r15                   ; 415f
    
    <bochs:24> info cpu
    CPU0:
    rsp: ffff8000_00207f40 
    rip: ffff8000_0010b06b
    

    相关文章

      网友评论

          本文标题:[OS64][027]源码调试:程序4-11 调试过程 objd

          本文链接:https://www.haomeiwen.com/subject/tpzhqctx.html