⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 builtins.c

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 C
📖 第 1 页 / 共 5 页
字号:
			tmp1 == 2 ? "2 = 1.44M floppy" :			tmp1 == 3 ? "3 = 2.88M floppy" : "Hard Disk");	/* No emulation mode uses 2048-byte sector size. */	if (tmp1 == 0 && buf_geom.sector_size != 2048)		goto failure_exec_format;//	chainloader_file[1] = tmp1;				/* 01: boot media type *///	chainloader_file[2] = ((tmp1 == 0) ? current_drive : (tmp1 == 4) ? 0x80 : 0x00);	/* 02: drive number */	if (tmp1 == 0)	/* no-emulation mode */	{		//kernel_type = KERNEL_TYPE_CHAINLOADER;		sprintf (chainloader_file, "(%d)%d+%d", current_drive, tmp, (i + 3) / 4);		chainloader_load_segment = tmp2;//0x0000;		chainloader_load_offset = 0;//0x7c00;		chainloader_load_length = i * 512;//0x200;		chainloader_skip_length = 0;		chainloader_boot_CS = tmp2;//0x0000;		chainloader_boot_IP = 0;//0x7c00;		//chainloader_ebx = 0;		//chainloader_ebx_set = 0;		chainloader_edx = current_drive;		chainloader_edx_set = 1;		//chainloader_disable_A20 = 0;				/* update lba_cd_boot if there are any maps */		if (! unset_int13_handler (0))	/* a successful unset */		{			if (drive_map_slot_empty (bios_drive_map[0]))			    if (atapi_dev_count == 0)			    {				errnum = ERR_NO_DRIVE_MAPPED;				goto failure_exec_format;			    }			lba_cd_boot = tmp;			set_int13_handler (bios_drive_map);		}		/* needn't clear disk buffer */		/* buf_drive = -1; */		/* buf_track = -1; */		return ! (errnum = 0);	}	/* floppy or hard drive emulation. LBA=tmp */	/*******************************************************/	/* read the first 512 bytes of the image at 0000:7C00  */	/*******************************************************/	filepos = tmp * 0x800;		/* we cannot use SCRATCHADDR because map_func and geometry_func may	 * use it. So we use 1 sector below 0x2B0000 instead. */	if (grub_read ((char *)(HMA_ADDR - 0x200), 512) != 512)		goto failure_exec_format;	if (tmp1 == 4)	{		if (probe_mbr ((struct master_and_dos_boot_sector *)(HMA_ADDR - 0x200), 0, 1, 0))		{			errnum = ERR_BAD_PART_TABLE;			goto failure_exec_format;		}	} else {		if (probe_bpb((struct master_and_dos_boot_sector *)(HMA_ADDR - 0x200)))		{			probed_total_sectors = (tmp1 == 1 ? 2400 : tmp1 == 2 ? 2880 : 5760);		}	}	/* map the image */	sprintf (chainloader_file, "--read-only --heads=0 --sectors-per-track=0 (%d)%d+%d (%d)", current_drive,			tmp,			(probed_total_sectors + 3) / 4, //0x3FFFFFFF,			(tmp1 == 4) ? 0x80 : 0x00);	tmp = ( (tmp1 == 4) ? (*(char *)0x475) : ((*(char*)0x410) & 1) );	disable_map_info = 1;	map_func (chainloader_file, flags);	disable_map_info = 0;	if (errnum)		goto failure_exec_format;	/* move the former fd0 or hd0 up. */	if (tmp)	{		sprintf (chainloader_file, "(%d) (%d)", (tmp1 == 4) ? 0x80 : 0x00, (tmp1 == 4) ? (0x80 + tmp) : 0x01);		map_func (chainloader_file, flags);		if (errnum)		{			if (debug > 0)			{				printf ("Failed 'map %s'(error=%d). But you may ignore it and continue to 'boot' the CD.\n", chainloader_file, errnum);			}			errnum = 0;		}	}	/* rehook */	unset_int13_handler (0);	if (drive_map_slot_empty (bios_drive_map[0]))	    if (atapi_dev_count == 0)	    {		errnum = ERR_NO_DRIVE_MAPPED;		goto failure_exec_format;	    }	set_int13_handler (bios_drive_map);	buf_drive = -1;	buf_track = -1;        grub_memmove ((char *)0x7C00, (char *)(HMA_ADDR - 0x200), 512);	sprintf (chainloader_file, "(%d)+1", (tmp1 == 4) ? 0x80 : 0x00);	chainloader_load_segment = 0;//tmp2;	chainloader_load_offset = 0x7c00;	chainloader_load_length = 512;	chainloader_skip_length = 0;	chainloader_boot_CS = 0;//tmp2;	chainloader_boot_IP = 0x7c00;	//chainloader_ebx = 0;	chainloader_ebx_set = 0;	chainloader_edx_set = 0;	//chainloader_disable_A20 = 0;	saved_drive = ((tmp1 == 4) ? 0x80 : 0x00);	chainloader_edx = saved_drive;	saved_partition = ((tmp1 == 4) ? 0x00FFFF : 0xFFFFFF);	return ! (errnum = 0);  }#endif /* ! GRUB_UTIL *///  if (debug > 0)//	printf ("Debug: chainloader_func: grub_open(%s)...", arg);  /* Open the file.  */  grub_open (arg);//  if (debug > 0)//	/* wipe out debug message. *///	printf ("\r                                                                             \r");  if (errnum)	goto failure;//  if (debug > 0)//	printf ("Debug: chainloader_func: grub_read(512 bytes)...");  /* Read the first block.  */  {    unsigned long len;    len = grub_read ((char *) SCRATCHADDR, 512);//    if (debug > 0)//	/* wipe out debug message. *///	printf ("\r                                                                             \r");    if (len != 512)	goto failure_exec_format;  }  if (chainloader_skip_length > filemax)  {	errnum = ERR_INVALID_SKIP_LENGTH;	goto failure_exec_format;  }//  hidden_sectors = part_start;    if (*((long *)SCRATCHADDR) == 0x49445324 /* $SDI */)    {	is_sdi = 1;	if (debug > 0)	    grub_printf("SDI signature: %s\n", (char *)(SCRATCHADDR));    }  else  if ((*(long long *)SCRATCHADDR | 0xFF00LL) == 0x4749464E4F43FFEBLL && filemax > 0x4000)    {	if (chainloader_load_segment == -1)		chainloader_load_segment = 0x0060;	if (chainloader_load_offset == -1)		chainloader_load_offset = 0;	if (chainloader_load_length == -1)		chainloader_load_length = filemax;	if (! chainloader_ebx_set)	{		chainloader_ebx = current_drive | ((current_partition >> 8) & 0xFF00);		chainloader_ebx_set = 1;	}	    	grub_close ();		/* FIXME: Where should the BPB be placed for FreeDOS's KERNEL.SYS?	 *	  In the current implementation it is placed at 0000:7C00	 *	  but has no effect, since the KERNEL.SYS body will later	 *	  overwrite 0000:7C00 on issuing the `boot' command.	 */		if ((chainloader_ebx & 0xFF00) == 0xFF00) /* check if partition number == 0xFF */		grub_sprintf ((char *)SCRATCHADDR, "(%d)+1", (chainloader_ebx & 0xff));	else		grub_sprintf ((char *)SCRATCHADDR, "(%d,%d)+1", (chainloader_ebx & 0xff), ((chainloader_ebx >> 8) & 0xff));	if (! grub_open ((char *)SCRATCHADDR))		goto failure;		/* Read the boot sector of the partition onto 0000:7C00  */	if (grub_read ((char *) SCRATCHADDR, 512) != 512)		goto failure_exec_format;	/* modify the hidden sectors */	/* FIXME: Does the boot drive number also need modifying? */		if (*((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS)))	    *((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS)) = part_start;	if (debug > 0)	  grub_printf("Will boot FreeDOS from drive=0x%x, partition=0x%x(hidden sectors=0x%x)\n",			current_drive/*(chainloader_ebx & 0x80)*/, ((current_partition >> 16) & 0xff), part_start);    }  else  if (*(short *)SCRATCHADDR == 0x5A4D && filemax > 0x10000 &&       *((unsigned short *) (SCRATCHADDR + BOOTSEC_SIG_OFFSET)) == 0      	/* && (*(long *)(SCRATCHADDR + 0xA2)) == 0 */ )    {      int err;            /* Read the second sector.  */      if (grub_read ((char *) SCRATCHADDR, 512) != 512)		goto failure_exec_format;      err = (*(short *)SCRATCHADDR != 0x4A42);      filepos += 0x200;	/* skip the third sector */            /* Read the fourth sector.  */      if (grub_read ((char *) SCRATCHADDR, 512) != 512)		goto failure_exec_format;      err |= (*((unsigned short *) (SCRATCHADDR + BOOTSEC_SIG_OFFSET)) != 0x534D);      /* Read the fifth sector.       * check the compress signature "CM" of IO.SYS of WinME */      if (grub_read ((char *) SCRATCHADDR, 512) != 512)		goto failure_exec_format;      if (! err)      {	if (chainloader_load_segment == -1)		chainloader_load_segment = 0x0070;	if (chainloader_load_offset == -1)		chainloader_load_offset = 0;	if (chainloader_load_length == -1)		chainloader_load_length = filemax;	if (chainloader_skip_length == 0)		chainloader_skip_length = 0x0800;	/* WinME support by bean. Thanks! */	// Input parameter for SYSINIT	// BX,AX: Start sector for the data area of FAT. It doesn't needs to	//        be set. However, we should at least clear BX, otherwise,	//        it would have some minor problem when booting WinME.	// DI:    Length of the boot code, don't need to be set.	// BP:    0x7C00, boot sector pointer, don't need to be set.	// DH:    Media ID (BS[0x15]) , 0xF0 for floppy, 0xF8 for harddisk	// DL:    Drive number (BS[0x40] for FAT32)	if (! chainloader_edx_set)	{		chainloader_edx = current_drive | ((current_partition >> 8) & 0xFF00);		chainloader_edx_set = 1;	}	if (! chainloader_ebx_set)	{		chainloader_ebx = 0;	// clear BX for WinME		chainloader_ebx_set = 1;	}	    	/* save partition number to the high word */	chainloader_edx = (chainloader_edx & 0xFF00FFFF) | ((chainloader_edx & 0xFF00) << 8);		// set media descriptor in DH for WinME	chainloader_edx = (chainloader_edx & 0xFFFF00FF) | 0xF000 | ((chainloader_edx & 0x80) << 4);			grub_close ();		/* FIXME: Where should the BPB be placed for MS-DOS's IO.SYS?	 *	  In the current implementation it is placed at 0000:7C00	 *	  but has no effect, since the IO.SYS body will later	 *	  overwrite 0000:7C00 on issuing the `boot' command.	 */		if ((chainloader_edx & 0xFF0000) == 0xFF0000) /* check if partition number == 0xFF */		grub_sprintf ((char *)SCRATCHADDR, "(%d)+1", (chainloader_edx & 0xff));	else		grub_sprintf ((char *)SCRATCHADDR, "(%d,%d)+1", (chainloader_edx & 0xff), ((chainloader_edx >> 16) & 0xff));	if (! grub_open ((char *)SCRATCHADDR))		goto failure;		/* Read the boot sector of the partition onto 0000:7C00  */	if (grub_read ((char *) SCRATCHADDR, 512) != 512)		goto failure_exec_format;	/* modify the hidden sectors */	/* FIXME: Does the boot drive number also need modifying? */		if (*((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS)))	    *((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS)) = part_start;	if (debug > 0)	  grub_printf("Will boot MS-DOS %c.x from drive=0x%x, partition=0x%x(hidden sectors=0x%x)\n",			((*(unsigned short *) SCRATCHADDR) == 0x4D43)? '8' : '7',			current_drive/*(chainloader_edx & 0x80)*/, ((current_partition >> 16) & 0xff), part_start);      }    }  else  if (((*(long *)SCRATCHADDR) & 0x00FF00FF) == 0x000100E9 && filemax > 0x30000 &&       (*((unsigned short *) (SCRATCHADDR + BOOTSEC_SIG_OFFSET)) != BOOTSEC_SIGNATURE))    {//grub_printf("current_drive=0x%x, current_partition=0x%x(part_start=0x%x)\n", current_drive, current_partition, part_start);	if (chainloader_load_segment == -1)		chainloader_load_segment = 0x2000;	if (chainloader_load_offset == -1)		chainloader_load_offset = 0;	if (chainloader_load_length == -1)		chainloader_load_length = filemax;	if (! chainloader_edx_set)	{		chainloader_edx = current_drive | ((current_partition >> 8) & 0xFF00);		chainloader_edx_set = 1;	}	    	grub_close ();		if ((chainloader_edx & 0xFF00) == 0xFF00)		grub_sprintf ((char *)SCRATCHADDR, "(%d)+1", (chainloader_edx & 0xff));	else		grub_sprintf ((char *)SCRATCHADDR, "(%d,%d)+1", (chainloader_edx & 0xff), ((chainloader_edx >> 8) & 0xff));	if (! grub_open ((char *)SCRATCHADDR))		goto failure;		/* Read the boot sector of the partition onto 0000:7C00  */	if (grub_read ((char *) SCRATCHADDR, SECTOR_SIZE) != SECTOR_SIZE)		goto failure_exec_format;//grub_printf("current_drive=0x%x, current_partition=0x%x(part_start=0x%x)\n", current_drive, current_partition, part_start);	/* modify the hidden sectors */	/* FIXME: Does the boot drive number also need modifying? */		if (*((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS)))	    *((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS)) = part_start;	if (debug > 0)	  grub_printf("Will boot NTLDR from drive=0x%x, partition=0x%x(hidden sectors=0x%x)\n", current_drive, ((current_partition >> 16) & 0xff), part_start);    }  else  if (((*(long long *)SCRATCHADDR) & 0xFFFFFFFFFFFFLL) == 0x7C40EAFALL && filemax > 0x2000 && filemax < 0x20000 &&       (*((unsigned short *) (SCRATCHADDR + 0x40)) == 0x892E) &&       (*((unsigned short *) (SCRATCHADDR + 0x45)) == 0x8C2E) &&       (*((unsigned long *) (SCRATCHADDR + 0x4A)) == 0xD08EC031) &&       (*((unsigned long *) (SCRATCHADDR + 0x4E)) == 0x8E7BD4BC)     )    {	if (buf_geom.sector_size != 2048)	{		if (debug > 0)			printf ("\nCannot chainload ISOLINUX from a non-CDROM device.\n");		goto failure_exec_format;	}	chainloader_load_segment = 0;	chainloader_load_offset = 0x7c00;	chainloader_load_length = filemax;	chainloader_edx = current_drive;	chainloader_edx_set = 1;	is_isolinux = 1;    }  else  /* If not loading it forcibly, check for the signature.  */  if (! force      && (*((unsigned short *) (SCRATCHADDR + BOOTSEC_SIG_OFFSET))	  != BOOTSEC_SIGNATURE))	goto failure_exec_format;  grub_close ();  /* if BPB exists, we can reliablly modify the hidden sectors. */  if (! probe_bpb((struct master_and_dos_boot_sector *)SCRATCHADDR))    if (*((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS)))        *((unsigned long *) (SCRATCHADDR + BOOTSEC_BPB_HIDDEN_SECTORS))          = part_start;  if (chainloader_load_length == -1)	  chainloader_load_length = filemax;  if (chainloader_load_length > 0xA0000)	  chainloader_load_length = 0xA0000;    grub_memmove ((char *)0x7C00, (char *)SCRATCHADDR, 512);  errnum = ERR_NONE;    return 1;failure_exec_format:  grub_close ();  if (errnum == ERR_NONE)	errnum = ERR_EXEC_FORMAT;failure:  chainloader_load_segment = chainloader_load_segment_orig;  chainloader_load_offset = chainloader_load_offset_orig;  chainloader_load_length = chainloader_load_length_orig;  chainloader_skip_length = chainloader_skip_length_orig;  chainloader_boot_CS = chainloader_boot_CS_orig;  chainloader_boot_IP = chainloader_boot_IP_orig;  chainloader_ebx = chainloader_ebx_orig;  chainloader_ebx_set = chainloader_ebx_set_orig;  chainloader_edx = chainloader_edx_orig;  chainloader_edx_set = chainloader_edx_set_orig;  chainloader_disable_A20 = chainloader_disable_A20_orig;  is_sdi = is_sdi_orig;  is_raw = is_raw_orig;  is_isolinux = is_isolinux_orig;  kernel_type = kernel_type_orig;  force = errnum;	/* backup the errnum */  grub_memmove ((char *)chainloader_file, (char *)chainloader_file_orig, sizeof(chainloader_file));  errnum = force;	/* restore the errnum */  return 0;		/* return failure */}static struct builtin builtin_chainloader ={  "chainloader",  chainloader_func,  BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,  "chainloader [--force] [--load-segment=LS] [--load-offset=LO]"  "\n[--load-length=LL] [--skip-length=SL] [--boot-cs=CS] [--boot-ip=IP]"  "\n[--ebx=EBX] [--edx=EDX] [--sdi] [--disable-a20] FILE",  "Load the chain-loader FILE. If --force is specified, then load it"  " forcibly, whether the boot loader signature is present or not."  " LS:LO specifies the load address other than 0000:7C00. LL specifies"  " the length of the boot image(between 512 and 640K). CS:IP specifies"  " the address where the boot image will gain control. EBX/EDX specifies"  " the EBX/EDX register value when the boot image gets control. Use --sdi"  " if FILE is a System Deployment Image, which is of the Windows XP"  " RAM boot file format. Use --disable-a20 if you wish to turn off"  " A20 when transferring cont

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -