当前位置: 首页 > 工具软件 > shoelace > 使用案例 >

shoelace源代码分析,bochs调试 readkernel()函数

狄宏大
2023-12-01

static inode_nr
readkernel F1(buffer *, bp)

{
  unsigned int build_base;        /* base of parameters left by build */
  unsigned int bpsize;            /* size of unprocessed part of bp */
  unsigned int bpinx;            /* index to unprocessed part of bp */

  if (! LoadStart)
    bpinx  = 0;
  else {
    LoadStart = 0;

    build_base = SECTOR_SIZE-8;
    if (memcmp(&((char *) bp)[SECTOR_SIZE-sizeof(signature)],
               (char *) &signature[0],
           sizeof(signature)) == 0)
      build_base -= sizeof(signature);

    if ( (long) (* (unsigned int *) (&((char *) bp)[build_base]) + 1)
         * SECTOR_SIZE != filesize) {
      printf("%s conflicting size information\n", filename);
      longjmp(errjmp, 1);
    }

    fsck_ds = * (unsigned int *) (&((char *) bp)[build_base+2]);
    fsck_pc = * (unsigned int *) (&((char *) bp)[build_base+4]);
    fsck_cs = * (unsigned int *) (&((char *) bp)[build_base+6]);

    bpinx = SECTOR_SIZE;
  }

  bpsize = sizeof(*bp) - bpinx;

  if (filesize > bpsize) {
    copyto((char *) bp + bpinx, LoadPoint, bpsize);
    filesize  -= bpsize;
    LoadPoint += bpsize;
    return 0;
  }

  copyto((char *) bp + bpinx, LoadPoint, (unsigned int) filesize);
  filesize = 1;
  return ROOT_INODE;
}


其中LoadPoint为long,既是占4个字节

b 0x00060ca7
c
b 0x60df4
c
b 0x64327
c
info r

b 0x60e7e

[ds:0x9f08] = LoadPoint    0x69f08

[ds:0x9f0c] = LoadStart    0x69f0c

filesize     0x6aedc

下面的第二个和第三个push其实是把LoadPoint变量分两次放入堆栈,因为LoadPoint占4个字节。


00060f5b: (                    ): push word ptr ss:[bp+0xfff8] ; ff76f8
00060f5e: (                    ): push word ptr [ds:0x9f0a] ; ff360a9f
00060f62: (                    ): push word ptr [ds:0x9f08] ; ff36089f
00060f66: (                    ): mov ax, word ptr ss:[bp+0xfff6] ; 8b46f6
00060f69: (                    ): add ax, word ptr ss:[bp+0x4] ; 034604
00060f6c: (                    ): push ax                   ; 50
00060f6d: (                    ): call 0xea                 ; e87af1


00060ff3: (                    ): push word ptr [ds:0xaedc] ; ff36dcae
00060ff7: (                    ): push word ptr [ds:0x9f0a] ; ff360a9f
00060ffb: (                    ): push word ptr [ds:0x9f08] ; ff36089f
00060fff: (                    ): mov ax, word ptr ss:[bp+0xfff6] ; 8b46f6
00061002: (                    ): add ax, word ptr ss:[bp+0x4] ; 034604
00061005: (                    ): push ax                   ; 50
00061006: (                    ): call 0xea                 ; e8e1f0

下面是两个函数内关键断点:

<bochs:33> b 0x60f6d
<bochs:34> b 0x61006

<bochs:35> c
(0) Breakpoint 5, 0x60f6d in ?? ()
Next at t=78053196
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:36> info r
...
esp            0xd7d2           0xd7d2
...

<bochs:37> x /10 0x6d7d2

[bochs]:

0x0006d7d2 <bogus+       0>:    0x0000d7ea      0x04000009

源地址为0x6d7ea,里面是Image的第一个块,目标地址为0x90000!

<bochs:39> x /20 0x6d7ea
[bochs]:
0x0006d7ea <bogus+       0>:    0x8e07c0b8      0x9000b8d8      0x00b9c08e      0x29f62901
0x0006d7fa <bogus+      16>:    0xeaa5f3ff      0x90000018      0xd88ec88c      0xd08ec08e
0x0006d80a <bogus+      32>:    0xbaff00bc      0x02b90000      0x0200bb00      0xcd0204b8
0x0006d81a <bogus+      48>:    0xba0a7313      0x00b80000      0xeb13cd00      0xb800b2e6
0x0006d82a <bogus+      64>:    0x13cd0800      0x892e00b5      0xb8013d0e      0xc08e9000




最后,我们把断点reankernel和断点<bochs:33> b 0x60f6d删除

保留断点<bochs:34> b 0x61006

因为0x1ea00需要123k既是123次才能加载完。


<bochs:71> c
(0) Breakpoint 6, 0x61006 in ?? ()
Next at t=78352131
(0) [0x00061006] 6000:1006 (unk. ctxt): call 0xea                 ; e8e1f0



最后的对应关系是

0x0000-0xc00  被加载到了 0x90000-0x90c00

0xa00-0x1ea00 被加载到了 0x10000-0x2ea00  对应关系是  +0xF600

  0x800-0xc00 被加载到了0x90800-0x90c00,同时

  0xa00-0xc00 被加载到了0x10000-0x10200

 

利用两个函数内的关键断点:我们在做一次
<bochs:33> b 0x60f6d
<bochs:34> b 0x61006

<bochs:1> b 0x60f6d
<bochs:2> b 0x61006
<bochs:3> c
(0) Breakpoint 1, 0x60f6d in ?? ()
Next at t=78053196
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:4> info r

esp            0xd7d2           0xd7d2

<bochs:5> x /2 0x6d7d2
[bochs]:
0x0006d7d2 <bogus+       0>:    0x0000d7ea      0x04000009
<bochs:6> c
(0) Breakpoint 1, 0x60f6d in ?? ()
Next at t=78055632
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:7> info r

esp            0xd7d2           0xd7d2

<bochs:8> x /2 0x6d7d2
[bochs]:
0x0006d7d2 <bogus+       0>:    0x0400d7ea      0x04000009
<bochs:9> c
(0) Breakpoint 1, 0x60f6d in ?? ()
Next at t=78058068
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:10> info r

esp            0xd7d2           0xd7d2

<bochs:11> x /2 0x6d7d2
[bochs]:
0x0006d7d2 <bogus+       0>:    0x0800d7ea      0x04000009
<bochs:12> c
(0) Breakpoint 1, 0x60f6d in ?? ()
Next at t=78061058
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:13> info r
esp            0xd7d2           0xd7d2

<bochs:14> x /2 0x6d7d2
[bochs]:
0x0006d7d2 <bogus+       0>:    0x0200d7ea      0x04000001
<bochs:15>



0x600ea 为 copyto()函数地址



<bochs:21> c
(0) Breakpoint 2, 0x60f6d in ?? ()
Next at t=78053196
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:22> b 0x600ea
<bochs:23> c
(0) Breakpoint 4, 0x600ea in ?? ()
Next at t=78053197
(0) [0x000600ea] 6000:00ea (unk. ctxt): xor ax, ax                ; 31c0
<bochs:24> c
(0) Breakpoint 2, 0x60f6d in ?? ()
Next at t=78055632
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:25> c
(0) Breakpoint 4, 0x600ea in ?? ()
Next at t=78055633
(0) [0x000600ea] 6000:00ea (unk. ctxt): xor ax, ax                ; 31c0


<bochs:26> c
(0) Breakpoint 2, 0x60f6d in ?? ()
Next at t=78058068
(0) [0x00060f6d] 6000:0f6d (unk. ctxt): call 0xea                 ; e87af1
<bochs:29> x /2 0x6d7d2
[bochs]:
0x0006d7d2 <bogus+       0>:    0x0800d7ea      0x04000009


<bochs:30> c
(0) Breakpoint 4, 0x600ea in ?? ()
Next at t=78058069
(0) [0x000600ea] 6000:00ea (unk. ctxt): xor ax, ax                ; 31c0

<bochs:31> c
(0) Breakpoint 4, 0x600ea in ?? ()
Next at t=78059173
(0) [0x000600ea] 6000:00ea (unk. ctxt): xor ax, ax                ; 31c0
<bochs:32> info r

esp            0xd7d0           0xd7d0

<bochs:34> x /3 0x6d7d0
[bochs]:
0x0006d7d0 <bogus+       0>:    0xd9ea0fda      0x00010000      0x00000200


红色是第一次是在readkernel()函数里面调用copyto

紫色是第二次是在readkernel()函数里面调用copyto

再下面是两次调用copyto第一次是在readkernel()函数里面调用,copy了1k字节

第二次调用copy了512字节。返回地址是0x60fda!也是在函数readkernel()里面

但是我们的源代码里面只调用了两次copyto(),所以这个源代码是为了启动minix用的,

为了能启动linux进行了修改!


00060fc4: (                    ): mov ax, 0x200             ; b80002
00060fc7: (                    ): push ax                   ; 50
00060fc8: (                    ): xor ax, ax                ; 31c0
00060fca: (                    ): mov bx, 0x1               ; bb0100
00060fcd: (                    ): push bx                   ; 53
00060fce: (                    ): push ax                   ; 50
00060fcf: (                    ): mov bx, word ptr ss:[bp+0x4] ; 8b5e04
00060fd2: (                    ): add bx, 0x200             ; 81c30002
00060fd6: (                    ): push bx                   ; 53
00060fd7: (                    ): call 0xea                 ; e810f1
00060fda: (                    ): add sp, 0x8               ; 83c408



大体的加载的思路是这样的:

bootsect部分不会运行,Image的的前3个k放到0x90000开始的地方

从0x00a00开始的部分被放置到了0x10000开始的地方,代替了bootsect里面加载system的任务。

然后进入0x90200既是setup部分进行运行!setup里面有移动0x10000到0x00000的任务,所以也可以顺利完成。

总之应该是为了适应linux的引导而需要修改一下shoelace,也就是这个shoelace不适合minix。

看看当年的group里面也有shoelace的讨论。

 类似资料: