你可比较一下上面的两个图片,除了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文件中,还是个递归函数。