mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[mbr] add LBA sector readout, as required by some BIOSes
* I'm looking at you, Dell Optiplex! * also fix boot in case no secondary bootable drive exists * also adds a readme
This commit is contained in:
		
							parent
							
								
									0f57ed1684
								
							
						
					
					
						commit
						1b7f88eb99
					
				
					 4 changed files with 159 additions and 94 deletions
				
			
		
							
								
								
									
										192
									
								
								res/mbr/mbr.S
									
										
									
									
									
								
							
							
						
						
									
										192
									
								
								res/mbr/mbr.S
									
										
									
									
									
								
							|  | @ -1,7 +1,7 @@ | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
| /* Rufus - The Reliable USB Formatting Utility, bootable USB MBR                */ | /* Rufus - The Reliable USB Formatting Utility, bootable USB MBR                */ | ||||||
| /*                                                                              */ | /*                                                                              */ | ||||||
| /* Copyright (c) 2011 Pete Batard <pete@akeo.ie>                                */ | /* Copyright (c) 2012 Pete Batard <pete@akeo.ie>                                */ | ||||||
| /*                                                                              */ | /*                                                                              */ | ||||||
| /* This program is free software; you can redistribute it and/or modify it      */ | /* This program is free software; you can redistribute it and/or modify it      */ | ||||||
| /* under the terms of the GNU General Public License as published by the Free   */ | /* under the terms of the GNU General Public License as published by the Free   */ | ||||||
|  | @ -26,6 +26,7 @@ | ||||||
| .code16			# MBR code is executed in x86 CPU real/16 bit mode | .code16			# MBR code is executed in x86 CPU real/16 bit mode | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
| /* Constants:                                                                   */ | /* Constants:                                                                   */ | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
|  | @ -34,14 +35,14 @@ DOT_NUMBER    = 0x04	# Number of dots to be printed before timeout | ||||||
| MBR_ADDR      = 0x7c00	# Same address for both original MBR and copy | MBR_ADDR      = 0x7c00	# Same address for both original MBR and copy | ||||||
| MBR_SIZE      = 0x200 | MBR_SIZE      = 0x200 | ||||||
| MBR_RESERVED  = 0x1b8	# Start of the reserved section (partition table, etc.) | MBR_RESERVED  = 0x1b8	# Start of the reserved section (partition table, etc.) | ||||||
| BUF_SEGMENT   = 0x3000  # Segment for the buffer |  | ||||||
| PT_MAX        = 0x04	# Number of partition entries in the partition table | PT_MAX        = 0x04	# Number of partition entries in the partition table | ||||||
| PT_ENTRY_SIZE = 0x10	# Size of a partition entry in the partition table | PT_ENTRY_SIZE = 0x10	# Size of a partition entry in the partition table | ||||||
| INT_RTC       = 0x08 | INT_RTC       = 0x08 | ||||||
| INT_DSK       = 0x13 | INT_DSK       = 0x13 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
| /* mbr: this section must reside at 0x00007c00, and be exactly 512 bytes        */ | /* MBR: this section must reside at 0x00007c00, and be exactly 512 bytes        */ | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
| .section main, "ax" | .section main, "ax" | ||||||
| .globl mbr			# label must be declared global for the linker | .globl mbr			# label must be declared global for the linker | ||||||
|  | @ -65,9 +66,9 @@ mbr: | ||||||
| 	push es | 	push es | ||||||
| 	mov  ds, ax		# Original MBR is in segment 0 | 	mov  ds, ax		# Original MBR is in segment 0 | ||||||
| 	mov  bx, 0x0413		# McAfee thinks we are a virus if we use 413 directly... | 	mov  bx, 0x0413		# McAfee thinks we are a virus if we use 413 directly... | ||||||
| 	mov  ax,[bx+0] | 	mov  ax,[bx] | ||||||
| 	dec  ax			# Remove 1KB from the RAM for our copy | 	dec  ax			# Remove 1KB from the RAM for our copy | ||||||
| 	mov  [bx+0],ax | 	mov  [bx],ax | ||||||
| 	shl  ax, 6		# Convert to segment address | 	shl  ax, 6		# Convert to segment address | ||||||
| 	sub  ax, MBR_ADDR>>4	# For convenience of disassembly, so that irrespective | 	sub  ax, MBR_ADDR>>4	# For convenience of disassembly, so that irrespective | ||||||
| 	mov  es, ax		# of the segment, our base address remains MBR_ADDR | 	mov  es, ax		# of the segment, our base address remains MBR_ADDR | ||||||
|  | @ -79,60 +80,33 @@ mbr: | ||||||
| 
 | 
 | ||||||
| # --------------------------------------------------------------------------- | # --------------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| # From this point forward, we are running the copy at a different segment from seg 0 | # From this point forward, we are running the copy at the same base but different segment | ||||||
| 0:	mov  ds, ax		# AX = ES = CS, only DS points back to old seg => fix this | 0:	mov  ds, ax		# AX = ES = CS, only DS points back to old seg => fix this | ||||||
| 	push es | 	push 0 | ||||||
| 	xor  ax, ax | 	pop  es			# ES remains set to segment 0 from here on | ||||||
| 	mov  es, ax | 	xor  ebx, ebx		# Sector #1 in 64 bit address mode (#0) | ||||||
| 	mov  bx, MBR_ADDR	# TODO optimize | 	mov  cx, 0x0001		# Sector #1 in CHS address mode (#1) | ||||||
| 	mov  ax, 0x0201 | 	mov  dx, 0x0081		# drive number (DL), track 0 (DH) | ||||||
| 	mov  cx, 0x0001 | 	call read_sector | ||||||
| 	mov  dx, 0x0081		# Check next bootable disk | 	jb   boot_usb		# If we couldn't get data => just boot USB | ||||||
| 	int  0x13		# DISK - READ SECTORS INTO MEMORY |  | ||||||
| 				# AL = number of sectors to read, CH = track, CL = sector |  | ||||||
| 				# DH = head, DL = drive, ES:BX -> buffer to fill |  | ||||||
| 				# Return: CF set on error, AH = status, AL = number of sectors read |  | ||||||
| 	jnb  read_success |  | ||||||
| 
 |  | ||||||
| read_failure:			# If we couldn't get data for second bootable, just boot USB |  | ||||||
| 	pop  es |  | ||||||
| 	jmp  boot_usb_no_rtc |  | ||||||
| 
 | 
 | ||||||
| read_success: | read_success: | ||||||
|  | 	mov  bx, offset partition_table | ||||||
| 	mov  cx, PT_MAX | 	mov  cx, PT_MAX | ||||||
| 	mov  bp, offset partition_table |  | ||||||
| 
 | 
 | ||||||
| check_table:			# check the partition table for an active (bootable) partition | check_table:			# check the partition table for an active (bootable) partition | ||||||
| 	cmpb es:[bp+0], 0x00 | 	cmpb es:[bx], 0x00 | ||||||
| 	jl   active_partition	# 0x80 or greater means the partition is active | 	jl   found_active	# 0x80 or greater means the partition is active | ||||||
| 	jnz  invalid_table	# anything between 0x01 and 0x7f is invalid | 	jnz  invalid_table	# anything between 0x01 and 0x7f is invalid | ||||||
| 	add  bp, PT_ENTRY_SIZE	# next partition | 	add  bx, PT_ENTRY_SIZE	# next partition | ||||||
| 	loop check_table | 	loop check_table | ||||||
| 
 | 
 | ||||||
| no_active: |  | ||||||
| 	pop  es |  | ||||||
| 	jmp  exit |  | ||||||
| 
 |  | ||||||
| active_partition: |  | ||||||
| 	push bp |  | ||||||
| 
 |  | ||||||
| check_one_active:		# check that all subsequent partitions are zero (only one active) |  | ||||||
| 	add  bp, PT_ENTRY_SIZE |  | ||||||
| 	dec  cx |  | ||||||
| 	jz   valid_active |  | ||||||
| 	cmpb es:[bp+0], 0x00 |  | ||||||
| 	jz   check_one_active |  | ||||||
| 	pop  bp |  | ||||||
| 
 |  | ||||||
| invalid_table: | invalid_table: | ||||||
| 	pop  es | 	jmp  boot_usb | ||||||
| 	jmp  exit |  | ||||||
| 
 | 
 | ||||||
| valid_active: | found_active: | ||||||
| 	pop  bp |  | ||||||
| 	pop  es |  | ||||||
| 	mov  si, offset prompt_string | 	mov  si, offset prompt_string | ||||||
| 	call print_string | 	call print_string	# Prompt the user | ||||||
| 	call flush_keyboard | 	call flush_keyboard | ||||||
| 
 | 
 | ||||||
| set_rtc_int_vect:		# Set the interrupt vector for CMOS real-time clock | set_rtc_int_vect:		# Set the interrupt vector for CMOS real-time clock | ||||||
|  | @ -143,21 +117,21 @@ set_rtc_int_vect:		# Set the interrupt vector for CMOS real-time clock | ||||||
| wait_for_keyboard: | wait_for_keyboard: | ||||||
| 	mov  ah, 0x01 | 	mov  ah, 0x01 | ||||||
| 	int  0x16		# KEYBOARD - CHECK BUFFER, DO NOT CLEAR | 	int  0x16		# KEYBOARD - CHECK BUFFER, DO NOT CLEAR | ||||||
| 	jnz  boot_usb		# Z is clear when characters are present in the buffer | 	jnz  boot_usb_rem_rtc	# Z is clear when characters are present in the buffer | ||||||
| 	mov  ah, 0x02 | 	mov  ah, 0x02 | ||||||
| 	int  0x16		# KEYBOARD - GET SHIFT STATUS | 	int  0x16		# KEYBOARD - GET SHIFT STATUS | ||||||
| 	and  al, 0x04		# AL = shift status bits | 	and  al, 0x04		# AL = shift status bits | ||||||
| 	jnz  boot_usb | 	jnz  boot_usb | ||||||
| 	cmpw ds:counter_dot, 0x0000 | 	cmpb ds:counter_dot, 0x00 | ||||||
| 	jg   short check_timeout | 	jg   short check_timeout | ||||||
| 
 | 
 | ||||||
| print_dot: | print_dot:			# Every so often, we print a dot | ||||||
| 	mov  si, offset dot_string | 	mov  si, offset dot_string | ||||||
| 	call print_string | 	call print_string | ||||||
| 	movw ds:counter_dot, DOT_TIMEOUT | 	movb ds:counter_dot, DOT_TIMEOUT | ||||||
| 
 | 
 | ||||||
| check_timeout: | check_timeout: | ||||||
| 	cmpw ds:counter_timeout, 0x0000 | 	cmpb ds:counter_timeout, 0x00 | ||||||
| 	jnz  wait_for_keyboard | 	jnz  wait_for_keyboard | ||||||
| 
 | 
 | ||||||
| boot_fixed_disk:		# Timeout occured => boot second bootable disk (non USB) | boot_fixed_disk:		# Timeout occured => boot second bootable disk (non USB) | ||||||
|  | @ -169,25 +143,23 @@ boot_fixed_disk:		# Timeout occured => boot second bootable disk (non USB) | ||||||
| boot_drive: | boot_drive: | ||||||
| 	pop  es | 	pop  es | ||||||
| 	pop  ds | 	pop  ds | ||||||
| 	mov  dl, 0x0080		# In both case, we pretend the disk is the first bootable | 	mov  dx, 0x0080		# In both case, we pretend the disk is the first bootable | ||||||
| 	jmp  0:MBR_ADDR | 	jmp  0:MBR_ADDR | ||||||
| 
 | 
 | ||||||
| # --------------------------------------------------------------------------- | # --------------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| boot_usb:			# Boot USB drive (0x80) | boot_usb_rem_rtc:		# Boot USB drive (0x80) | ||||||
| 	call restore_rtc_vect	# Remove our RTC override | 	call restore_rtc_vect	# Remove our RTC override | ||||||
|  | boot_usb: | ||||||
| 	call flush_keyboard	# Make sure the keyboard buffer is clear | 	call flush_keyboard	# Make sure the keyboard buffer is clear | ||||||
| boot_usb_no_rtc: |  | ||||||
| 	mov  bx, offset partition_table | 	mov  bx, offset partition_table | ||||||
| 	mov  dx, es:[bx] | 	mov  dx, ds:[bx] | ||||||
| 	mov  cx, es:[bx+2] | 	mov  cx, ds:[bx+2] | ||||||
| 	xor  ax, ax | 	mov  ebx, ds:[bx+8]	# Must come last since it modifies BX | ||||||
| 	mov  es, ax		# make sure ES is set to seg 0 for copy | 	call read_sector | ||||||
| 	mov  ax, 0x0201 |  | ||||||
| 	mov  bx, MBR_ADDR |  | ||||||
| 	int  0x13 |  | ||||||
| 	jnb  boot_drive | 	jnb  boot_drive | ||||||
| exit: | 
 | ||||||
|  | exit:				# failed to read PBR from USB - exit back to BIOS | ||||||
| 	pop  es | 	pop  es | ||||||
| 	pop  ds | 	pop  ds | ||||||
| 	retf | 	retf | ||||||
|  | @ -197,17 +169,56 @@ exit: | ||||||
| /* Subroutines                                                                  */ | /* Subroutines                                                                  */ | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
| 
 | 
 | ||||||
|  | read_sector:			# Read a single sector in either CHS or LBA mode | ||||||
|  | 				# EBX = LBA sector address (32 bit), CH = track | ||||||
|  | 				# CL = sector,  DL = drive number, DH = head | ||||||
|  | 	pusha			# save all registers | ||||||
|  | 	mov  ah, 0x41 | ||||||
|  | 	mov  bx, 0x55aa | ||||||
|  | 	int  0x13 | ||||||
|  | 	jb   no_ext		# failure to get ext | ||||||
|  | 	cmp  bx, 0xaa55 | ||||||
|  | 	jnz  no_ext | ||||||
|  | 	test cx, 1		# is packet access supported? | ||||||
|  | 	jz   no_ext | ||||||
|  | 
 | ||||||
|  | ext:	# http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D42h:_Extended_Read_Sectors_From_Drive | ||||||
|  | 	popa | ||||||
|  | 	push ds | ||||||
|  | 	xor  eax, eax | ||||||
|  | 	mov  ds, ax		# We'll use the stack for DAP, which is in seg 0 | ||||||
|  | 	push eax		# bits 32-63 of sector address (set to 0) | ||||||
|  | 	push ebx		# bits 0-31 of sector address (EBX) | ||||||
|  | 	push ax			# destination segment | ||||||
|  | 	push MBR_ADDR		# destination address | ||||||
|  | 	inc  ax | ||||||
|  | 	push ax			# number of sectors to be read (1) | ||||||
|  | 	push 0x0010		# size of DAP struct | ||||||
|  | 	mov  si, sp		# DAP address (= stack) | ||||||
|  | 	mov  ah, 0x42		# Extended Read Sectors From Drive | ||||||
|  | 	int  0x13 | ||||||
|  | 	lahf | ||||||
|  | 	add  sp,0x10 | ||||||
|  | 	sahf | ||||||
|  | 	pop  ds | ||||||
|  | 	ret | ||||||
|  | 
 | ||||||
|  | no_ext:	# http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D02h:_Read_Sectors_From_Drive | ||||||
|  | 	popa | ||||||
|  | 	mov  bx, MBR_ADDR	# CL, CH, DL, DH, ES are already set | ||||||
|  | 	mov  ax, 0x0201 | ||||||
|  | 	int  0x13 | ||||||
|  | 	ret | ||||||
|  | 
 | ||||||
|  | # --------------------------------------------------------------------------- | ||||||
|  | 
 | ||||||
| set_int_vect:			# Set the interrupt vector | set_int_vect:			# Set the interrupt vector | ||||||
| 	cli			# SI = pointer to backup vector (must contain the interrupt #) | 	cli			# SI = pointer to backup vector (must contain the interrupt #) | ||||||
| 	push es			# DX = pointer to interrupt |  | ||||||
| 	xor  ax, ax |  | ||||||
| 	mov  es, ax |  | ||||||
| 	mov  bx, ds:[si] | 	mov  bx, ds:[si] | ||||||
| 	mov  eax, es:[bx]	# Backup the original vector | 	mov  eax, es:[bx]	# Backup the original vector | ||||||
| 	mov  ds:[si], eax | 	mov  ds:[si], eax | ||||||
| 	mov  es:[bx], dx | 	mov  es:[bx], dx | ||||||
| 	mov  es:[bx+2], cs | 	mov  es:[bx+2], cs | ||||||
| 	pop  es |  | ||||||
| 	sti | 	sti | ||||||
| 	ret | 	ret | ||||||
| 
 | 
 | ||||||
|  | @ -215,13 +226,9 @@ set_int_vect:			# Set the interrupt vector | ||||||
| 
 | 
 | ||||||
| restore_rtc_vect:		# Restore the interrupt vector for RTC | restore_rtc_vect:		# Restore the interrupt vector for RTC | ||||||
| 	cli | 	cli | ||||||
| 	push es |  | ||||||
| 	xor  ax, ax |  | ||||||
| 	mov  es, ax |  | ||||||
| 	mov  bx, INT_RTC*4 | 	mov  bx, INT_RTC*4 | ||||||
| 	mov  eax, ds:rtc_interrupt_org | 	mov  eax, ds:rtc_interrupt_org | ||||||
| 	mov  es:[bx], eax | 	mov  es:[bx], eax | ||||||
| 	pop  es |  | ||||||
| 	sti | 	sti | ||||||
| 	ret | 	ret | ||||||
| 
 | 
 | ||||||
|  | @ -238,23 +245,15 @@ flush_keyboard:			# Flush the keyboard buffer | ||||||
| 
 | 
 | ||||||
| # --------------------------------------------------------------------------- | # --------------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| print_string:			# Print a NUL terminated string to console | print_string:			# Print NUL terminated string in DS:SI to console | ||||||
| 	push ax |  | ||||||
| 	push bx |  | ||||||
| 
 |  | ||||||
| ps_putchar: |  | ||||||
| 	lodsb | 	lodsb | ||||||
| 	cmp  al, 0x00 | 	cmp  al, 0x00 | ||||||
| 	jz   ps_exit | 	jz   0f | ||||||
| 	mov  ah, 0x0e | 	mov  ah, 0x0e | ||||||
| 	mov  bx, 0x0007		# BH = display page, BL = foreground color | 	mov  bx, 0x0007		# BH = display page, BL = foreground color | ||||||
| 	int  0x10		# VIDEO - WRITE CHARACTER AND ADVANCE CURSOR | 	int  0x10		# VIDEO - WRITE CHARACTER AND ADVANCE CURSOR | ||||||
| 	jmp  ps_putchar | 	jmp  print_string | ||||||
| 
 | 0:	ret | ||||||
| ps_exit: |  | ||||||
| 	pop  bx |  | ||||||
| 	pop  ax |  | ||||||
| 	ret |  | ||||||
| 
 | 
 | ||||||
| # --------------------------------------------------------------------------- | # --------------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
|  | @ -267,6 +266,23 @@ disk_swap:			# Swap disks 0x80 and 0x81 | ||||||
| 	xor  dl, 0x01 | 	xor  dl, 0x01 | ||||||
| 0:	ret | 0:	ret | ||||||
| 
 | 
 | ||||||
|  | # --------------------------------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | .if 0
 | ||||||
|  | print_hex:			# Hex dump of the word at address ES:BX | ||||||
|  | 	mov  cx, 0x04 | ||||||
|  | 	mov  dx, es:[bx] | ||||||
|  | 0:	rol  dx, 0x04 | ||||||
|  | 	mov  ax, 0xe0f | ||||||
|  | 	and  al, dl | ||||||
|  | 	daa | ||||||
|  | 	add  al, 0xF0 | ||||||
|  | 	adc  al, 0x40 | ||||||
|  | 	int  0x10 | ||||||
|  | 	loop 0b | ||||||
|  | 	ret | ||||||
|  | .endif | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
| /* Interrupt overrides                                                          */ | /* Interrupt overrides                                                          */ | ||||||
|  | @ -276,10 +292,10 @@ disk_swap:			# Swap disks 0x80 and 0x81 | ||||||
| rtc_interrupt: | rtc_interrupt: | ||||||
| 	pushf | 	pushf | ||||||
| 	cli | 	cli | ||||||
| 	cmpw cs:counter_timeout, 0x0000 | 	cmpb cs:counter_timeout, 0x00 | ||||||
| 	jz   rtc_exec_org | 	jz   rtc_exec_org | ||||||
| 	decw cs:counter_dot | 	decb cs:counter_dot | ||||||
| 	decw cs:counter_timeout | 	decb cs:counter_timeout | ||||||
| 
 | 
 | ||||||
| rtc_exec_org: | rtc_exec_org: | ||||||
| rtc_interrupt_org = .+1		# Same trick used by the LILO mapper | rtc_interrupt_org = .+1		# Same trick used by the LILO mapper | ||||||
|  | @ -315,8 +331,8 @@ dsk_interrupt_org = .+1 | ||||||
| int13_cmd:	.byte 0x00 | int13_cmd:	.byte 0x00 | ||||||
| prompt_string:	.string "\r\nPress any key to boot from USB." | prompt_string:	.string "\r\nPress any key to boot from USB." | ||||||
| dot_string = 	.-2		# Reuse the end of previous string | dot_string = 	.-2		# Reuse the end of previous string | ||||||
| counter_timeout:.word DOT_NUMBER*DOT_TIMEOUT + 1 | counter_timeout:.byte DOT_NUMBER*DOT_TIMEOUT + 1 | ||||||
| counter_dot:	.word DOT_TIMEOUT | counter_dot:	.byte DOT_TIMEOUT | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /********************************************************************************/ | /********************************************************************************/ | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								res/mbr/mbr.bin
									
										
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								res/mbr/mbr.bin
									
										
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										49
									
								
								res/mbr/readme.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								res/mbr/readme.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | ||||||
|  | Rufus: The Reliable USB Formatting Utility - Custom MBR | ||||||
|  | 
 | ||||||
|  | # Description | ||||||
|  | 
 | ||||||
|  | This directory contains all the resources required to create an MBR that prompts | ||||||
|  | the user for boot selection, when a second bootable device (typically bootable | ||||||
|  | fixed HDD) is reported by the BIOS. | ||||||
|  | 
 | ||||||
|  | This aims at mimicking the Microsoft Windows optical installation media feature, | ||||||
|  | which may be necessary on for WinPE 2.x or earlier based installations. | ||||||
|  | 
 | ||||||
|  | # Compilation | ||||||
|  | 
 | ||||||
|  | Any gcc suite (except possibly the X-Code one on OS-X) should be able to compile | ||||||
|  | the MBR by invoking 'make'. A 'make dis', that produces a disassembly dump is | ||||||
|  | also provided for your convenience. | ||||||
|  | 
 | ||||||
|  | # Primer | ||||||
|  | 
 | ||||||
|  | The way this bootloader achieves the feature highlighted above is as follows: | ||||||
|  | 1. An attempt to read the MBR of the second bootable drive (0x81) is made | ||||||
|  |    through INT_13h (in either CHS or LBA mode depending on the extensions  | ||||||
|  |    detected) | ||||||
|  | 2. If that attempts succeeds, then the partition table from the newly read MBR | ||||||
|  |    is checked for an active/bootable entry. | ||||||
|  | 3. If such a partition is found, a prompt is displayed to the user and an RTC  | ||||||
|  |    timer interrupt (INT_8h) override is added so that dots are displayed at | ||||||
|  |    regular interval. Then the keyboard is checked for entry. | ||||||
|  | 4. If the user presses a key, the first partition boot record from the USB is | ||||||
|  |    read (according to the values found in the USB MBR partition table) and | ||||||
|  |    executed | ||||||
|  | 5. If no key is pressed, then an INT_13h (disk access interrupt) override is | ||||||
|  |    added to masquerade the second bootable drive (0x81) as the first one (0x80) | ||||||
|  |    so that the Windows second stage installer, or any other program relying on | ||||||
|  |    BIOS disk access, behave as if there was no USB drive inserted. | ||||||
|  | 6. In case there was a failure to read the second bootable drive's MBR, or no | ||||||
|  |    active partition was detected there, the USB is booted without prompts. | ||||||
|  | 
 | ||||||
|  | # Limitations | ||||||
|  | 
 | ||||||
|  | * If you are using software RAID or a non-conventional setup, the second | ||||||
|  |   bootable disk may not be accessible through the BIOS and therefore the USB | ||||||
|  |   will always be booted | ||||||
|  | * If the bootable HDD uses LILO, a "LILO - Keytable read/checksum error" will | ||||||
|  |   be displayed when trying to boot it. | ||||||
|  | * This MBR currently does not masquerade the bootable USB drive as secondary | ||||||
|  |   (0x81) therefore an installation program ran from USB to install an OS on | ||||||
|  |   an HDD may still configure that disk as the second drive, and prevent it to | ||||||
|  |   properly boot later on. | ||||||
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 206, 289 | IDD_DIALOG DIALOGEX 12, 12, 206, 289 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| EXSTYLE WS_EX_APPWINDOW | EXSTYLE WS_EX_APPWINDOW | ||||||
| CAPTION "Rufus v1.1.6.155" | CAPTION "Rufus v1.1.6.156" | ||||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| BEGIN | BEGIN | ||||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,248,50,14 |     DEFPUSHBUTTON   "Start",IDC_START,94,248,50,14 | ||||||
|  | @ -73,7 +73,7 @@ BEGIN | ||||||
|     DEFPUSHBUTTON   "OK",IDOK,231,175,50,14,WS_GROUP |     DEFPUSHBUTTON   "OK",IDOK,231,175,50,14,WS_GROUP | ||||||
|     CONTROL         "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL, |     CONTROL         "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL, | ||||||
|                     "SysLink",WS_TABSTOP,46,47,114,9 |                     "SysLink",WS_TABSTOP,46,47,114,9 | ||||||
|     LTEXT           "Version 1.1.6 (Build 155)",IDC_STATIC,46,19,78,8 |     LTEXT           "Version 1.1.6 (Build 156)",IDC_STATIC,46,19,78,8 | ||||||
|     PUSHBUTTON      "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP |     PUSHBUTTON      "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP | ||||||
|     EDITTEXT        IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL |     EDITTEXT        IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL | ||||||
|     LTEXT           "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 |     LTEXT           "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 | ||||||
|  | @ -223,8 +223,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 1,1,6,155 |  FILEVERSION 1,1,6,156 | ||||||
|  PRODUCTVERSION 1,1,6,155 |  PRODUCTVERSION 1,1,6,156 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -241,13 +241,13 @@ BEGIN | ||||||
|         BEGIN |         BEGIN | ||||||
|             VALUE "CompanyName", "akeo.ie" |             VALUE "CompanyName", "akeo.ie" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "1.1.6.155" |             VALUE "FileVersion", "1.1.6.156" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus.exe" |             VALUE "OriginalFilename", "rufus.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "1.1.6.155" |             VALUE "ProductVersion", "1.1.6.156" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue