_main:
pop ax | return address (offset)
pop ax | return address (segment)
mov cx,#BYTESPERCLICK | click size
mul cx | make into 32 bit address
mov di,dx | save address
mov si,ax
mov bx,cs | code segment
mov dx,#begdata | start of data segment
test dx,dx
jnz comid | common i&d
mov ax,#endtext | end of text
add ax,cx | round up to next click
dec ax
div cx | dx cleared from above
add bx,ax | point at data segment
可以对比得到shoelace确实被加载到了0x10000!
call _shoemain
可以在0x10035处下断点:b 0x10035
接力棒交给了shoelace
shoelace由shoelace.x和shoe.c等文件编译而成。
shoelace.x里面有个_main:最后调用了
call _shoemain
shoemain()函数在shoe.c文件里,调用了runningshoe()函数,runningshoe()函数调用了shoe()函数
static void
shoe F0()
{
...
/* Load Minix by configuration file if possible */
if (configok) {
shoe()函数会加载配置文件,/etc/config,既是cnf
然后把开启kernel文件,会显示/etc/system/kernel没有发现,
然后是加载boot,我们这里的配置文件里是Image。
上面的loadParts就是shoe()函数中 printf("\nLoad Parts");打印出来的。
下面再看loadbuilt()函数,
return loadimage(name, (INODEFN) readkernel);
loadimage()函数最后调用了dozones()函数,并把readkernel()函数指针传给了dozones()函数
static int
loadimage F2(char *, name, INODEFN, fn)
{
...
/* Scan the zones encompassed by this inode */
dozones(&ibuf.i_zone[0], fn);
return 1;
}
下面进入dozones()函数,在shoefs.c文件里面
/*
* Scan all the zones
*
* Scan all the zones - direct, indirect and doubly indirect - and
* return the result which will be a non-zero inode number. Scanning
* will stop as soon as a result is known.
*/
inode_nr
dozones F2(zone_nr *, zp, INODEFN, fn)
{
inode_nr node; /* result of scan */
int len; /* number of zones in list */
int ind; /* indirection */
for (ind = 0, len = NR_DZONE_NUM; ind < 3; zp += len, ind++, len = 1)
if ((node = scanzone(zp, ind, len, fn)) != 0)
return node;
return 0;
}
里面调用了scanzone()函数,不同的是传递的fn不一样,这次是readkernel()函数。
加载到内存后,然后进入startminix()函数,在shoelace.x文件里,最终我们看到了一个跳转语句
jumpminix:
seg cs
jmpi @fsck_vector | jump to minix
也就是把控制权交给了image,到这里分析结束。
migrate()定义在shoelace.x,作用是移动代码到内存的最后64Kb处。
在shoe.c文件的runningshoe()函数内被调用
| Move Bootstrap
|
| Move the bootstrap from its current location to the last 64kb of
| memory. After doing so it will return the base address to which it
| has moved the bootstrap.
|
| ADDRESS migrate(void)
这里的base为0x60000处。