V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dogedoge
V2EX  ›  汇编

6.828 lab1 Exercise 2 死循环问题

  •  1
     
  •   dogedoge · 2020-04-21 11:59:06 +08:00 · 4492 次点击
    这是一个创建于 1464 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://pdos.csail.mit.edu/6.828/2018/labs/lab1/

    版本:

    • qemu:QEMU emulator version 1.5.3 (qemu-kvm-1.5.3-167.el7_7.4), Copyright (c) 2003-2008 Fabrice Bellard
    • centos:CentOS-7-x86_64-Minimal-1908
    • gdb:GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-115.el7

    The ROM BIOS 这个章节,A 窗口 make qemu-gdb,B 窗口 make gdb

    A:

    /usr/libexec/qemu-kvm -drive file=obj/kern/kernel.img,index=0,media=disk,format=raw -serial mon:stdio -gdb tcp::25000 -D qemu.log  -S
    VNC server running on `::1:5900'
    

    B si 单步调试:

    [f000:fff0]    0xffff0: ljmp   $0xf000,$0xe05b
    [f000:e05b]    0xfe05b: cmpl   $0x0,%cs:0x69c8
    [f000:e062]    0xfe062: jne    0xfd0f7
    [f000:e066]    0xfe066: xor    %dx,%dx
    [f000:e068]    0xfe068: mov    %dx,%ss
    [f000:e070]    0xfe070: mov    $0xf1399,%edx
    [f000:e076]    0xfe076: jmp    0xfcf8c
    [f000:cf8c]    0xfcf8c: cli
    [f000:cf8d]    0xfcf8d: cld
    [f000:cf8e]    0xfcf8e: mov    %eax,%ecx
    [f000:cf91]    0xfcf91: mov    $0x8f,%eax
    [f000:cf97]    0xfcf97: out    %al,$0x70
    [f000:cf9b]    0xfcf9b: in     $0x92,%al
    [f000:cf9d]    0xfcf9d: or     $0x2,%al
    [f000:cf9f]    0xfcf9f: out    %al,$0x92
    [f000:cfa4]    0xfcfa4: lidtw  %cs:0x69b8
    [f000:cfaa]    0xfcfaa: lgdtw  %cs:0x6974
    [f000:cfb0]    0xfcfb0: mov    %cr0,%ecx
    [f000:cfb3]    0xfcfb3: and    $0x1fffffff,%ecx
    [f000:cfba]    0xfcfba: or     $0x1,%ecx
    [f000:cfbe]    0xfcfbe: mov    %ecx,%cr0
    

    切入 PE 之后:

    The target architecture is assumed to be i386
    => 0xfcfc9:     mov    $0x10,%ecx
    => 0xfcfce:     mov    %ecx,%ds
    => 0xfcfd0:     mov    %ecx,%es
    => 0xfcfd2:     mov    %ecx,%ss
    => 0xfcfd6:     mov    %ecx,%gs
    => 0xfcfd8:     jmp    *%edx
    => 0xf1399:     sub    $0x8,%esp
    => 0xf139c:     movl   $0xf4254,0x4(%esp)
    => 0xf13a4:     movl   $0xf390a,(%esp)
    => 0xf13ab:     call   0xee4dd
    => 0xee4dd:     lea    0x8(%esp),%ecx
    => 0xee4e1:     mov    0x4(%esp),%edx
    => 0xee4e5:     mov    $0xf4200,%eax
    => 0xee4ea:     call   0xedd5a
    => 0xedd5a:     push   %ebp
    => 0xedd5b:     push   %edi
    => 0xedd5c:     push   %esi
    => 0xedd5d:     push   %ebx
    => 0xedd5e:     sub    $0xc,%esp
    => 0xedd61:     mov    %eax,%ebx
    => 0xedd63:     mov    %edx,0x4(%esp)
    => 0xedd67:     mov    %ecx,%ebp
    => 0xedd69:     mov    0x4(%esp),%esi
    => 0xedd6d:     movsbl (%esi),%edx
    => 0xedd70:     test   %dl,%dl
    => 0xedd72:     je     0xedfb6
    => 0xedd78:     cmp    $0x25,%dl
    => 0xedd7b:     jne    0xede1b
    => 0xede1b:     mov    %ebx,%eax
    => 0xede1d:     call   0xec570
    => 0xec570:     mov    %eax,%ecx
    => 0xec572:     movsbl %dl,%edx
    => 0xec575:     call   *(%ecx)
    => 0xec565:     mov    %edx,%eax
    => 0xec567:     mov    0xf683c,%dx
    => 0xec56e:     out    %al,(%dx)
    => 0xec577:     ret
    
    => 0xede22:     jmp    0xedfaa
    => 0xedfaa:     lea    0x1(%esi),%eax
    => 0xedfad:     mov    %eax,0x4(%esp)
    => 0xedfb1:     jmp    0xedd69
    => 0xedd69:     mov    0x4(%esp),%esi
    => 0xedd6d:     movsbl (%esi),%edx
    => 0xedd70:     test   %dl,%dl
    => 0xedd72:     je     0xedfb6
    => 0xedd78:     cmp    $0x25,%dl
    => 0xedd7b:     jne    0xede1b
    => 0xede1b:     mov    %ebx,%eax
    => 0xede1d:     call   0xec570
    => 0xec570:     mov    %eax,%ecx
    => 0xec572:     movsbl %dl,%edx
    => 0xec575:     call   *(%ecx)
    => 0xec565:     mov    %edx,%eax
    => 0xec567:     mov    0xf683c,%dx
    => 0xec56e:     out    %al,(%dx)
    => 0xec577:     ret
    ...
    

    中间隔开的那一段一直到 ... 就是死循环,但是如果这个时候 c continue 的话 A 又可以进 kernel,而且试了断点,并没有进 0x7c00

    找到一篇:https://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-qemu/33203642#33203642,把 A 窗口换成直接执行:

    /usr/libexec/qemu-kvm -drive file=obj/kern/kernel.img,index=0,media=disk,format=raw -serial mon:stdio -D qemu.log -S -s
    

    其实就是换了 gdb TCP 1234 端口,然后按照 stackoverflow 上在 B 连 1234:

    target remote localhost:1234
    

    最终 si 还是进了死循环... 另外试了 -bios 参数,也确实是使用的 seabios.bin

    已经查不动了,求大佬解答~

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3920 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:10 · PVG 13:10 · LAX 22:10 · JFK 01:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.