shoelace源代码分析之bootlace

来源:互联网 发布:局域网qq监控软件 编辑:程序博客网 时间:2024/05/29 19:33


你可比较一下上面的两个图片,除了shoelace外是一模一样的。

第一个图片是img镜像的0x400开始的,第二个图片是bootlace文件的0x20开始的。



如果说主引导记录被winiboot覆盖,那么minix分区第一个启动块被bootlace覆盖。

对于的命令分别是

laceup -w 1 /dev/hd5 和 laceup /dev/hd6 wini


在shoelace.h里面有下面的定义

#define BOOTLACENAME    "BootLace"
#define SHOELACENAME    "ShoeLace"

#define WINIBOOTFILE    "/etc/winiboot"
#define    BOOTLACEFILE    "/etc/bootlace"
#define SHOELACEFILE    "/shoelace"
#define DISKTABFILE    "/etc/disktab"
#define CONFIGFILE    "/etc/config"



laceup.c文件的结构很清晰,就两个功能函数winiboot()函数和bootlace()函数。

winiboot()函数作用是把winiboot覆盖主引导记录,对应的命令是laceup -w 1 /dev/hd5 

bootlace()函数作用是把bootlace覆盖分区的引导块,对应的命令是 laceup /dev/hd6 wini


int
main F2(int, argc, char **, argv)

{
  int sw;                /* switch */
  char error;                /* error occurred */
  char wini;                /* wini boot */

  for (wini = error = 0; (sw = getopt(argc, argv, "w:")) != EOF; ) {
    switch (sw) {
    case 'w':
      if (optarg[0] == 0 || optarg[1] != 0)
        error = 1;
      else {
        switch (optarg[0]) {
    case '1': wini  = 1; break;
    case '2': wini  = 2; break;
    case '3': wini  = 3; break;
    case '4': wini  = 4; break;
    default:  error = 1; break;
    }
      }
      break;
    default:  error = 1; break;
    }
  }

  if (error || (wini && optind != argc-1) || (!wini && optind != argc-2)) {
    fprintf(stderr, "Usage: %s [-w partition] file [disktype]\n", argv[0]);
    exit(1);
  }

  if (wini)
    winiboot(argv[optind], wini);
  else
    bootlace(argv[optind], argv[optind+1]);

  return 0;
}


bootlacesrc=    shoehead.x bootlace.x shoeasm.x \
        shoebfs.c shoeboot.c

bootlace依赖于bootlace.x和shoeboot.c和shoeasm.x和shoebfs.c和shoeboot.c文件。

调用关系首先是bootlace.x里面的

_bootentry:

    jmpi    _loadlace,LOADSEG    | start load code

|************************************************************************
| The real boot code begins here. None of the addressing registers,     *
| except cs, is correct at this stage.                                  *
|************************************************************************

_loadlace:
...

下面是看是否是硬盘引导还是软盘引导。

如果是硬盘引导取得硬盘的参数,然后是

...

    j    readshoehorn

...

    call    _shoehorn        | shoe horn the code in

    calli    0,BOOTSEG

然后是调用了_shoehorn


而shoehorn()函数在shoeboot.c文件里面。

下面说明shoeboot.c文件:就两个函数shoehorn()函数和readshoe()函数。

/* Locate ShoeLace then load it */

通过shoeboot.c里面的一句注释就能明白了,定位/shoelace文件和加载到内存。

然后把接力棒交给shoelace

shoehorn()函数调用的readblock()函数在bootlace.x文件中,

shoehorn()函数通过调用scanzone()函数来调用readshoe()函数函数。

readshoe()函数调用的copyviabufptr()函数也在bootlace.x文件中。

scanzone()函数在shoebfs.c文件中,还是个递归函数。


1 0