|
@天涯海角:
2、SYSLINUX 在引导扇区记录了LDLINUX.SYS的首扇区地址,启动时根据这个地址去加载LDLINUX.SYS,不依赖于文件系统,而LDINUX.SYS文件中又记录了文件长度信息和占用的扇区信息,所以其文件名无所谓。而 G4D 是根据文件系统,从文件分配表中去找 GRLDR,这两者是大不一样的
1、它这个校验方法比较特殊,是一个负校验,首先把 LDLINUX.SYS 占用的扇区列出来(不包括最开始一个扇区的地址,因为LDLINUX.SYS首扇区地址已经记录在引导扇区),放到 0x30 开始的地方,然后把 0x2C 开始的四字节清空,令 x=0x03eb202fe,令 dwlen=整个 LDLINUX.SYS 文件大小 / 4;然后用 x 依次减去这个文件的每个 DWORD(四字节),最后得到的就是校验和,放到 0x2C 处。
以下是 SYSLINUX 发行包里面的代码:
- int syslinux_patch(const uint32_t * sectors, int nsectors,
- int stupid, int raid_mode)
- {
- unsigned char *patcharea, *p;
- int nsect = (syslinux_ldlinux_len + 511) >> 9;
- uint32_t csum;
- int i, dw;
- if (nsectors < nsect)
- return -1;
- /* Patch in options, as appropriate */
- if (stupid) {
- /* Access only one sector at a time */
- set_16(syslinux_bootsect + 0x1FC, 1);
- }
- i = get_16(syslinux_bootsect + 0x1FE);
- if (raid_mode)
- set_16(syslinux_bootsect + i, 0x18CD); /* INT 18h */
- set_16(syslinux_bootsect + 0x1FE, 0xAA55);
- /* First sector need pointer in boot sector */
- set_32(syslinux_bootsect + 0x1F8, *sectors++);
- nsect--;
- /* Search for LDLINUX_MAGIC to find the patch area */
- for (p = syslinux_ldlinux; get_32(p) != LDLINUX_MAGIC; p += 4) ;
- patcharea = p + 8;
- /* Set up the totals */
- dw = syslinux_ldlinux_len >> 2; /* COMPLETE dwords! */
- set_16(patcharea, dw);
- set_16(patcharea + 2, nsect); /* Does not include the first sector! */
- /* Set the sector pointers */
- p = patcharea + 8;
- memset(p, 0, 64 * 4);
- while (nsect--) {
- set_32(p, *sectors++);
- p += 4;
- }
- /* Now produce a checksum */
- set_32(patcharea + 4, 0);
- csum = LDLINUX_MAGIC;
- for (i = 0, p = syslinux_ldlinux; i < dw; i++, p += 4)
- csum -= get_32(p); /* Negative checksum */
- set_32(patcharea + 4, csum);
- return 0;
- }
复制代码
[ 本帖最后由 Pauly 于 2009-11-13 08:57 编辑 ] |
|