📄 builtins.c
字号:
{ errnum = ERR_INVALID_LOAD_SEGMENT; goto failure; } } else if (grub_memcmp (arg, "--load-offset=", 14) == 0) { p = arg + 14; if (! safe_parse_maxint (&p, &chainloader_load_offset)) goto failure; if (chainloader_load_offset < 0 || chainloader_load_offset > 0xffff) { errnum = ERR_INVALID_LOAD_OFFSET; goto failure; } } else if (grub_memcmp (arg, "--load-length=", 14) == 0) { p = arg + 14; if (! safe_parse_maxint (&p, &chainloader_load_length)) goto failure; if (chainloader_load_length < 512 || chainloader_load_length > 0xa0000) { errnum = ERR_INVALID_LOAD_LENGTH; goto failure; } } else if (grub_memcmp (arg, "--skip-length=", 14) == 0) { p = arg + 14; if (! safe_parse_maxint (&p, &chainloader_skip_length)) goto failure; if (chainloader_skip_length < 0) { errnum = ERR_INVALID_SKIP_LENGTH; goto failure; } } else if (grub_memcmp (arg, "--boot-cs=", 10) == 0) { p = arg + 10; if (! safe_parse_maxint (&p, &chainloader_boot_CS)) goto failure; if (chainloader_boot_CS < 0 || chainloader_boot_CS > 0xffff) { errnum = ERR_INVALID_BOOT_CS; goto failure; } } else if (grub_memcmp (arg, "--boot-ip=", 10) == 0) { p = arg + 10; if (! safe_parse_maxint (&p, &chainloader_boot_IP)) goto failure; if (chainloader_boot_IP < 0 || chainloader_boot_IP > 0xffff) { errnum = ERR_INVALID_BOOT_IP; goto failure; } } else if (grub_memcmp (arg, "--ebx=", 6) == 0) { p = arg + 6; if (! safe_parse_maxint (&p, (int *)(void *)&chainloader_ebx)) goto failure; chainloader_ebx_set = 1; } else if (grub_memcmp (arg, "--edx=", 6) == 0) { p = arg + 6; if (! safe_parse_maxint (&p, (int *)(void *)&chainloader_edx)) goto failure; chainloader_edx_set = 1; } else if (grub_memcmp (arg, "--sdi", 5) == 0) { is_sdi = 1; } else if (grub_memcmp (arg, "--raw", 5) == 0) { is_raw = 1; } else if (grub_memcmp (arg, "--disable-a20", 13) == 0) { chainloader_disable_A20 = 1; } else break; arg = skip_to (0, arg); } if (grub_strlen(saved_dir) + grub_strlen(arg) + 20 >= sizeof(chainloader_file)) { errnum = ERR_WONT_FIT; goto failure; } if (*arg == '/') { if (saved_partition != 0xFFFFFF) { if ((saved_partition & 0xFF00) == 0xFF00) grub_sprintf (chainloader_file, "(%d,%d)%s%s", saved_drive, (char)(saved_partition>>16), saved_dir, arg); else if ((saved_partition & 0xFF0000) == 0xFF0000) grub_sprintf (chainloader_file, "(%d,%c)%s%s", saved_drive, (char)(saved_partition>>8) + 'a', saved_dir, arg); else grub_sprintf (chainloader_file, "(%d,%d,%c)%s%s", saved_drive, (char)(saved_partition>>16), (char)(saved_partition>>8) + 'a', saved_dir, arg); } else grub_sprintf (chainloader_file, "(%d)%s%s", saved_drive, saved_dir, arg); } else if (*arg == '(' && arg[1] == ')') { if (saved_partition != 0xFFFFFF) { if ((saved_partition & 0xFF00) == 0xFF00) grub_sprintf (chainloader_file, "(%d,%d)%s", saved_drive, (char)(saved_partition>>16), arg + 2); else if ((saved_partition & 0xFF0000) == 0xFF0000) grub_sprintf (chainloader_file, "(%d,%c)%s", saved_drive, (char)(saved_partition>>8) + 'a', arg + 2); else grub_sprintf (chainloader_file, "(%d,%d,%c)%s", saved_drive, (char)(saved_partition>>16), (char)(saved_partition>>8) + 'a', arg + 2); } else grub_sprintf (chainloader_file, "(%d)%s", saved_drive, arg + 2); } else if (*arg != '(') { if (saved_partition != 0xFFFFFF) { if ((saved_partition & 0xFF00) == 0xFF00) grub_sprintf (chainloader_file, "(%d,%d)%s", saved_drive, (char)(saved_partition>>16), arg); else if ((saved_partition & 0xFF0000) == 0xFF0000) grub_sprintf (chainloader_file, "(%d,%c)%s", saved_drive, (char)(saved_partition>>8) + 'a', arg); else grub_sprintf (chainloader_file, "(%d,%d,%c)%s", saved_drive, (char)(saved_partition>>16), (char)(saved_partition>>8) + 'a', arg); } else grub_sprintf (chainloader_file, "(%d)%s", saved_drive, arg); } else grub_memmove (chainloader_file, arg, 255); chainloader_file[255]=0; errnum = ERR_NONE; if ((is_sdi) || (is_raw)) return 1;// if (debug > 0)// printf ("Debug: chainloader_func: set_device(%s) ...", arg); /* Get the drive number. */ filename = set_device (arg);// if (debug > 0)// /* wipe out debug message. */// printf ("\r \r"); if (errnum) { /* No device specified. Default to the root device. */ current_drive = saved_drive; //current_partition = saved_partition; filename = arg; errnum = 0; } if (filename == 0) filename = arg;#ifndef GRUB_UTIL /* check bootable cdrom */ if (*filename == 0 || *filename == ' ' || *filename == '\t') { //check_bootable_cdrom (current_drive); //unsigned long i; unsigned long tmp; unsigned short tmp1; unsigned short tmp2;// struct geometry tmp_geom; tmp = current_drive; /* check bootable type of drive (tmp) *///grub_printf ("get_diskinfo(0x%X)\n", tmp); /* Get the geometry. This ensures that the drive is present. */ if (get_diskinfo (tmp, &tmp_geom)) { errnum = ERR_NO_DISK; goto failure; }//grub_printf ("get_diskinfo ok.\n"); /* open the drive */ grub_sprintf ((char *)SCRATCHADDR, "(0x%X)+0x%X", tmp, tmp_geom.total_sectors);//grub_printf ("grub_open(%s)\n", SCRATCHADDR); if (! grub_open ((char *)SCRATCHADDR)) goto failure; //grub_printf ("filemax=%X\n", filemax); /****************************************/ /* read the EL Torito Volume Descriptor */ /****************************************/ //filemax = 0x12 * 0x800; filepos = 0x11 * 0x800; if (grub_read ((char *)SCRATCHADDR, 512) != 512) goto failure_exec_format;//grub_printf ("grub_read ok.\n"); /* check the EL Torito Volume Descriptor */ if (memcmp ((char *)SCRATCHADDR, "\0CD001\1EL TORITO SPECIFICATION\0", 31)) goto failure_exec_format; /* get absolut start sector number for boot catalog */ tmp = *(unsigned long *)((char *)SCRATCHADDR + 0x47); /********************************************/ /* read the first 512 bytes of Boot Catalog */ /********************************************/ //filemax = (tmp + 1) * 0x800; filepos = tmp * 0x800; if (grub_read ((char *)SCRATCHADDR, 512) != 512) goto failure_exec_format; /*******************************/ /* check the Validation Entry */ /*******************************/ tmp1 = 0; for (i = 0; i < 16; i++) { tmp = *(((unsigned short *)(char *)SCRATCHADDR) + i); tmp1 += tmp; if ((i == 0 && tmp != 1) || (i == 15 && tmp != 0xAA55)) break; } if (tmp1 || i < 16) goto failure_exec_format; /* Boot Record Volume Descriptor format * * Offset Type Description * ------ ---- ---------------------------------------------- * 0 Byte Boot Record Indicator, must be 0 * * 1-5 Characters ISO-9660 Identifier, must be "CD001" * * 6 Byte Version of this descriptor, must be 1 * * 7-26 Characters Boot System Identifier, must be * "EL TORITO SPECIFICATION" padded with 0's. * * 27-46 Characters Unused, must be 0. * * 47-4A Dword LBA of the first sector of Boot Catalog. * * 4B-7FF Characters Unused, must be 0. * */ /* Validation Entry format * * Offset Type Description * ------ ---- ---------------------------------------------- * 0 Byte Header ID, must be 01 * * 1 Byte Platform ID * 0 = 80x86 * 1 = Power PC * 2 = Mac * * 2-3 Word Reserved, must be 0 * * 4-1B Characters ID string. This is intended to identify the * manufacturer/developer of the CD-ROM. * * 1C-1D Word Checksum Word. This sum of all the words in * this record should be 0. * * 1E Byte Key byte, must be 55. This value is included * in the checksum. * * 1F Byte Key byte, must be AA. This value is included * in the checksum. * */ /* Initial/Default Entry format * * Offset Type Description * ------ ---- ---------------------------------------------- * 0 Byte Boot Indicator. 88=Bootable, 00=Not Bootable * * 1 Byte Boot media type. * 0 = No Emulation * 1 = 1.2 meg diskette * 2 = 1.44 meg diskette * 3 = 2.88 meg diskette * 4 = Hard Disk(drive 80) * * 2 Word Load Segment. 0 for 7C0 * * 4 Byte System Type. * * 5 Byte Unused, must be 0. * * 6 Word Sector Count. This is the number of virtual/ * emulated sectors the system will store at Load * Segment during the initial boot procedure. * * 8 DWord Load RBA. This is the start address of the * virtual disk. CD's use Relative/Logical block * addressing. * * C Bytes Unused, must be 0's. * */ /* Specification Packet format * * Offset Type Description * ------ ---- ---------------------------------------------- * 0 Byte Packet Size, currently 13 * * 1 Byte Boot media type. This specifies what media the * boot image is intended to emulate in bits 0-3. * Bits 6-7 are specific to the type of system. * * Bits 0-3 count as follows: * * 0: No Emulation * 1: 1.2 meg diskette * 2: 1.44 meg diskette * 3: 2.88 meg diskette * 4: Hard Disk (drive C) * * 5-F: Reserved, invalid at this time * * bits 4-5 - Reserved, must be 0 * bit 6 - Image contains an ATAPI driver, * bytes 8 & 9 refer to IDE interface * bit 7 - Image contains SCSI drivers, * bytes 8 & 9 refer to SCSI interface * * 2 Byte Drive Number. This is the drive number on * which emulation is being initiated or * terminated. This must be 0 for a floppy image, * 80 for a bootable hard disk, and 81-FF for a * "non-bootable" or "no emulation" drive. * * 3 Byte Controller Index. This specifies the controller * number of the specified CD drive. * * 4-7 Dword Logical Block Address for the disk image to be * emulated. * * 8-9 Word Device Specification. For SCSI controllers byte * 8 is the LUN and PUN of the CD Drive, byte 9 is * the Bus number. For IDE controllers the low * order bit of byte 8 specifies master/slave * device, 0 = master. * * A-B Word User Buffer Segment. If this field is non-zero * it specifies the segment of a user supplied 3k * buffer for caching CD reads. This buffer will * begin at Segment:0. * * C-D Word Load Segment. This is the load address for the * initial boot image. If this value is 0, the * system will use the traditional segment of 7C0. * If this value is non-zero the system will use * the specified address. This field is only valid * for function 4C. * * E-F Word Sector Count. This is the number of virtual * sectors the system will store at Load Segment * during the initial boot procedure. This field * is only valid for function 4C. * * 10 Byte Bits 0-7 of the cylinder count. This should * match the value returned in CH when INT 13 * function 08 is invoked. * * 11 Byte This is the value returned in the CL register * when INT 13 function 08 is invoked. Bits 0-5 * are the sector count. Bits 6 and 7 are the high * order 2 bits of the cylinder count. * * 12 Byte This is the head count, it should match the * value in DH when INT 13 Function 08 is invoked. * */ /***********************************/ /* check the Initial/Default Entry */ /***********************************/ /* XXX: assume Initial/Default Entry is always at offset 0x20 */ tmp = *(unsigned char *)(SCRATCHADDR + 0x20); /* Boot Indicator. 88=Bootable, 00=Not Bootable */ if (tmp != 0x88) goto failure_exec_format; tmp = *((unsigned char *)SCRATCHADDR + 0x25); /* Unused byte, must be 0. */ if (tmp) goto failure_exec_format; tmp2 = *((unsigned short *)((unsigned char *)SCRATCHADDR + 0x22)); /* Load Segment */ if (debug > 0) printf ("\nLoad segment: 0x%X\t", tmp2); if (tmp2 == 0) tmp2 = 0x7C0;// *(unsigned short *)&(chainloader_file[0x0C]) = tmp2; /* 0C-0D: load segment */ tmp = *((unsigned char *)SCRATCHADDR + 0x24); /* System Type */ if (debug > 0) printf ("System Type: 0x%X\t", tmp); i = *((unsigned short *)((unsigned char *)SCRATCHADDR + 0x26)); /* Sector Count */ if (debug > 0) printf ("Sector Count: 0x%X\n", i);// *(unsigned short *)&(chainloader_file[0x0E]) = i; /* 0E-0F: sector count in 512-byte sectors */ tmp = *((unsigned long *)((unsigned char *)SCRATCHADDR + 0x28)); /* Load RBA */ if (debug > 0) printf ("Load RBA: 0x%X\t", tmp);// *(unsigned long *)&(chainloader_file[4]) = tmp; /* 04-07: LBA of the image to be emulated */ tmp1 = *((unsigned char *)SCRATCHADDR + 0x21); /* Boot media type */ if (tmp1 > 4) goto failure_exec_format; if (debug > 0) printf ("Boot Type: %s\n", tmp1 == 0 ? "0 = No Emulation" : tmp1 == 1 ? "1 = 1.2M floppy" :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -