shoelace源代码分析,bochs调试 readkernel()函数
static inode_nrreadkernel F1(buffer *, bp){ unsigned int build_base; /* base of parameters left by build */ unsigned int bpsize; /* size of unprocessed part of bp */ u
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
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的讨论。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)