您的位置:首页 > 编程语言

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

2014-01-02 19:34 435 查看
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,同时

[b]  0xa00-0xc00 被加载到了0x10000-0x10200
[/b]

 

利用两个函数内的关键断点:我们在做一次
<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

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

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

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

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

[b][b]为了能启动linux进行了修改!
[/b][/b]



[b][b]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
[/b][/b]





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

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

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

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

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

看看当年的group里面也有shoelace的讨论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: