shoelace源代码分析之shoe.c

shoelace源代码分析之shoe.c_第1张图片


_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) {
    printf("\nLoad Parts");
    if (buildimage(&cnf, 0) && patchimage())
      startkernel(&cnf);
    printf("\nLoad Image\n");
    if (loadbuilt(cnf.c_boot))
      startminix(0, (char *) 0, 0);
  }

/* Start the command line interpreter */
  shoecli();
}


shoe()函数会加载配置文件,/etc/config,既是cnf
然后把开启kernel文件,会显示/etc/system/kernel没有发现,

然后是加载boot,我们这里的配置文件里是Image。


shoelace源代码分析之shoe.c_第2张图片

上面的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处。

你可能感兴趣的:(shoelace,shoe.c)