From bfbb9d2ed533e4637a07a0a7637effcd5200187c Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 19 Feb 2020 14:22:14 +0000 Subject: [PATCH] [mbr] replace gpt.S with a more generic msg.S * msg.S now reads an ASCII message (with escaped colour sequences) from the following blocks, which is both more flexible and allows for more content to be displayed. * Also adds Bochs testing to the MBR build facility --- res/mbr/Makefile | 40 ++++---- res/mbr/bochsrc.bxrc | 58 ++++++++++++ res/mbr/gpt.S | 100 -------------------- res/mbr/gpt.bin | Bin 512 -> 0 bytes res/mbr/msg.S | 220 +++++++++++++++++++++++++++++++++++++++++++ res/mbr/msg.bin | Bin 0 -> 512 bytes res/mbr/msg.txt | 11 +++ res/mbr/readme.txt | 8 +- src/rufus.rc | 10 +- 9 files changed, 325 insertions(+), 122 deletions(-) create mode 100644 res/mbr/bochsrc.bxrc delete mode 100644 res/mbr/gpt.S delete mode 100644 res/mbr/gpt.bin create mode 100644 res/mbr/msg.S create mode 100644 res/mbr/msg.bin create mode 100644 res/mbr/msg.txt diff --git a/res/mbr/Makefile b/res/mbr/Makefile index 4e6067d1..35a5dd73 100644 --- a/res/mbr/Makefile +++ b/res/mbr/Makefile @@ -17,23 +17,23 @@ # along with this program; if not, see . # -OBJECTS = mbr.o -TARGET = mbr +TEST_TARGET = msg -ASM = gcc -CC = gcc -LD = ld -OBJDUMP = objdump -OBJCOPY = objcopy -CFLAGS = -m32 -LDFLAGS = -nostartfile +ASM = gcc +CC = gcc +LD = ld +OBJDUMP = objdump +OBJCOPY = objcopy +CFLAGS = -m32 +LDFLAGS = -nostartfile +BOCHS = "C:/Program Files/Bochs/bochsdbg.exe" .PHONY: all clean -all: $(TARGET).bin +all: mbr.bin msg.bin clean: - @-rm -f -v *.o *.out $(TARGET).map + @-rm -f -v *.o *.out *.map *.bin *.img *.ini %.o: %.c Makefile @echo "[CC] $@" @@ -44,17 +44,25 @@ clean: @$(ASM) -c -o $*.o $(CFLAGS) $< # Produce a disassembly dump, for verification purposes -dis: $(TARGET).out +dis: $(TEST_TARGET).out @echo "[DIS] $<" @$(OBJCOPY) -O binary -j .main --set-section-flags .main=alloc,load,readonly,code $< main.bin @$(OBJDUMP) -D -bbinary -mi8086 -Mintel main.bin | less @-rm -f main.bin -$(TARGET).out: $(OBJECTS) $(TARGET).ld - @echo "[LD] $@" - @$(LD) $(LDFLAGS) -T$(TARGET).ld -o $@ $(OBJECTS) -Map $(TARGET).map +# Run the MBR in a Bochs environment (append msg.txt in subsequent blocks) +test: $(TEST_TARGET).bin + @test -s $(BOCHS) || { echo "Error: $(BOCHS) was not found on this system"; exit 1; } + @cat $(TEST_TARGET).bin msg.txt > disk.img + @truncate -c -s 10M disk.img + -@$(BOCHS) -f bochsrc.bxrc -q -$(TARGET).bin: $(TARGET).out +%.out: %.o mbr.ld + @echo "[LD] $@" + @$(LD) $(LDFLAGS) -Tmbr.ld -o $@ $< -Map $*.map + +%.bin: %.out @echo "[MBR] $@" @# Note: -j only works for sections that have the 'ALLOC' flag set @$(OBJCOPY) -O binary -j .main --gap-fill=0x00 $< $@ + @-rm -f $< $*.map diff --git a/res/mbr/bochsrc.bxrc b/res/mbr/bochsrc.bxrc new file mode 100644 index 00000000..389a25d5 --- /dev/null +++ b/res/mbr/bochsrc.bxrc @@ -0,0 +1,58 @@ +# configuration file generated by Bochs +plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, gameport=true, iodebug=true +config_interface: win32config +display_library: win32, options="gui_debug" +memory: host=32, guest=32 +romimage: file="C:\Program Files\Bochs\BIOS-bochs-latest", address=0x00000000, options=none +vgaromimage: file="C:\Program Files\Bochs\VGABIOS-lgpl-latest" +boot: disk +floppy_bootsig_check: disabled=0 +# no floppya +# no floppyb +ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata0-master: type=disk, path="C:\Projects\rufus\res\mbr\disk.img", mode=flat, cylinders=64, heads=10, spt=32, sect_size=512, model="Virtual HDD", biosdetect=auto, translation=lba +ata0-slave: type=none +ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata1-master: type=none +ata1-slave: type=none +ata2: enabled=false +ata3: enabled=false +optromimage1: file=none +optromimage2: file=none +optromimage3: file=none +optromimage4: file=none +optramimage1: file=none +optramimage2: file=none +optramimage3: file=none +optramimage4: file=none +pci: enabled=1, chipset=i440fx +vga: extension=vbe, update_freq=5, realtime=1 +cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 +cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " +cpuid: mmx=true, apic=xapic, simd=sse2, sse4a=false, misaligned_sse=false, sep=true +cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true +cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true +cpuid: vmx=1 +print_timestamps: enabled=0 +debugger_log: - +magic_break: enabled=1 +port_e9_hack: enabled=0 +private_colormap: enabled=0 +clock: sync=none, time0=local, rtc_sync=0 +# no cmosimage +log: - +logprefix: %t%e%d +debug: action=ignore +info: action=report +error: action=report +panic: action=ask +keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none +mouse: type=ps2, enabled=false, toggle=ctrl+mbutton +sound: waveoutdrv=win, waveout=none, waveindrv=win, wavein=none, midioutdrv=win, midiout=none +speaker: enabled=true, mode=sound +parport1: enabled=true, file=none +parport2: enabled=false +com1: enabled=true, mode=null +com2: enabled=false +com3: enabled=false +com4: enabled=false diff --git a/res/mbr/gpt.S b/res/mbr/gpt.S deleted file mode 100644 index 4419238e..00000000 --- a/res/mbr/gpt.S +++ /dev/null @@ -1,100 +0,0 @@ -/********************************************************************************/ -/* GPT - A protective MBR that displays a notice if a user attempts to boot a */ -/* GPT drive in BIOS/Legacy mode. */ -/* */ -/* Copyright (c) 2019 Pete Batard */ -/* */ -/* 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 */ -/* Software Foundation, either version 3 of the License, or (at your option) */ -/* any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, but WITHOUT */ -/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ -/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ -/* more details. */ -/* */ -/* You should have received a copy of the GNU General Public License along with */ -/* this program; if not, see . */ -/* */ -/********************************************************************************/ - -/********************************************************************************/ -/* GNU Assembler Settings: */ -/********************************************************************************/ -.intel_syntax noprefix -.code16 -/********************************************************************************/ - -/********************************************************************************/ -/* Constants: */ -/********************************************************************************/ -MBR_ADDR = 0x7c00 -MBR_SIZE = 0x200 -MBR_RESERVED = 0x1b8 # Start of the reserved section (partition table, etc.) -PT_MAX = 0x04 # Number of partition entries in the partition table -PT_ENTRY_SIZE = 0x10 # Size of a partition entry in the partition table - -/********************************************************************************/ -/* MBR: This section resides at 0x00007c00 and is exactly 512 bytes */ -/********************************************************************************/ -.section main, "ax" -.globl mbr -mbr: - inc cx - dec bx - inc bp - dec di - cld - xor ax, ax - mov ds, ax - mov si, offset sep - call print_string - mov si, offset hdr - call print_string - mov si, offset sep - call print_string - mov si, offset txt - call print_string - hlt - -print_string: - lodsb - cmp al, 0x00 - jz 0f - mov ah, 0x0e - mov bx, 0x0007 - int 0x10 - jmp print_string -0: ret - -/********************************************************************************/ -/* Data section */ -/********************************************************************************/ -sep: - .string "****************************************\r\n" -hdr: - .string "*** ERROR: LEGACY BOOT OF UEFI MEDIA ***\r\n" -txt: - .ascii "\r\n" \ - "This drive can only boot in UEFI mode.\r\n" \ - "It can not boot in BIOS/Legacy mode.\r\n" \ - "\r\n" \ - "If you want to boot this drive in BIOS/Legacy mode, you\r\n" \ - "should recreate it in Rufus using the following settings:\r\n" \ - "* Partition scheme -> MBR\r\n" \ - "* Target system -> BIOS...\r\n" \ - "\0" - -/********************************************************************************/ -/* From offset 0x1b8, the MBR contains the partition table and signature data */ -/********************************************************************************/ - .org MBR_RESERVED -disk_signature: - .space 0x04 -filler: - .space 0x02 -partition_table: - .space PT_ENTRY_SIZE * PT_MAX -mbr_signature: - .word 0xAA55 diff --git a/res/mbr/gpt.bin b/res/mbr/gpt.bin deleted file mode 100644 index e3aee1cc1a904d5b40588992de161f1476bc0f89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmc(aJxjwt7{|}47>Eddf&W~z(zS??YAV5&NNfke5L2?JVCze2WH$R9tb`y%= z?CwVhxQU~KmsSy++?lGF+&PDCcK ecZfkZs-+>%r-EQgLn5o|_5N1NzQq2`Mt7fk5qYBk diff --git a/res/mbr/msg.S b/res/mbr/msg.S new file mode 100644 index 00000000..1b23051d --- /dev/null +++ b/res/mbr/msg.S @@ -0,0 +1,220 @@ +/********************************************************************************/ +/* MSG - A protective MBR that displays an ASCII message located in the */ +/* following sectors. */ +/* */ +/* Copyright (c) 2019-2020 Pete Batard */ +/* */ +/* 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 */ +/* Software Foundation, either version 3 of the License, or (at your option) */ +/* any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but WITHOUT */ +/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ +/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ +/* more details. */ +/* */ +/* You should have received a copy of the GNU General Public License along with */ +/* this program; if not, see . */ +/* */ +/********************************************************************************/ + +/********************************************************************************/ +/* GNU Assembler Settings: */ +/********************************************************************************/ +.intel_syntax noprefix +.code16 +/********************************************************************************/ + +/********************************************************************************/ +/* Constants: */ +/********************************************************************************/ +MBR_ADDR = 0x7c00 +MBR_RESERVED = 0x1b8 # Start of the reserved section (partition table, etc.) +NB_SECTORS = 0x08 # Number of sectors to read +PT_MAX = 0x04 # Number of partition entries in the partition table +PT_ENTRY_SIZE = 0x10 # Size of a partition entry in the partition table + +/********************************************************************************/ +/* Reference list of colours: */ +/* You can escape these numeric values in your message text to set the colours * +/* for the background and foreground. For instance "\17HIGHLIGHT" will display */ +/* light grey text (0x07) over a blue (0x01) background */ +/********************************************************************************/ +BLACK = 0x00 +BLUE = 0x01 +GREEN = 0x02 +CYAN = 0x03 +RED = 0x04 +MAGENTA = 0x05 +BROWN = 0x06 +LIGHT_GREY = 0x07 +DARK_GREY = 0x08 +LIGHT_BLUE = 0x09 +LIGHT_GREEN = 0x0a +LIGHT_CYAN = 0x0b +LIGHT_RED = 0x0c +LIGHT_MAGENTA = 0x0d +LIGHT_YELLOW = 0x0e +WHITE = 0x0f + +/********************************************************************************/ +/* MBR: This section resides at 0x00007c00 and is exactly 512 bytes */ +/********************************************************************************/ +.section main, "ax" +.globl mbr +mbr: +// xchg bx, bx # Uncomment to trigger Bochs magic breakpoint + inc cx + dec bx + inc bp + dec di + cld + xor ax, ax + cli # Disable interrupts when fiddling with the stack + mov ss, ax # First order of the day it to set up the stack + mov sp, MBR_ADDR # This places the stack right before the MBR copy in RAM + sti + mov ds, ax # MBR and stack reside in segment 0 + mov bx, 0x0413 # McAfee thinks we are a virus if we use 413 directly... + mov ax,[bx] + sub ax, NB_SECTORS / 2 # Amount of RAM we need to read the message sectors + mov [bx],ax + shl ax, 6 # Convert to segment address + mov es, ax # Keep allocated RAM segment in ES + +clear_display: + mov bh, 0x07 + mov ax, 0x007f + int 0x10 # Set Video Mode to 640x480 16 color graphics (VGA) + xor bx, bx + xor cx, cx + mov dx, 0x184f + mov ax, 0x0600 + int 0x10 # Clear screen + xor dx, dx + mov ah, 0x02 + int 0x10 # Set cursor pos to top left + +read_sectors: # Copy the next sectors into RAM + 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 + xor eax, eax + push eax # bits 32-63 of sector address + inc eax + push eax # bits 0-31 of sector address + push es # destination segment + push 0x0000 # destination address + push NB_SECTORS # number of sectors to be read + 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 + jmp check_error + +no_ext: # http://en.wikipedia.org/wiki/INT_13H#INT_13h_AH.3D02h:_Read_Sectors_From_Drive + mov ax, 0x0200 + NB_SECTORS + mov cx, 0x0002 # Sector address (starts at 1) + mov dx, 0x0080 # Drive ID + xor bx, bx # Destination address in ES + int 0x13 + +check_error: + mov bx, 0x0007 # Default text to light grey on black + jc display_err + +display_msg: # Display the message + xor si, si + mov ax, es + mov ds, ax + call print_msg + jmp halt_system + +display_err: # Read error -> display shorter message from this MBR + mov si, offset err_msg + call print_msg + +halt_system: # Halt the system + hlt + jmp halt_system # Just in case... + +/********************************************************************************/ +/* Subroutines */ +/********************************************************************************/ + +print_msg: # Print NUL terminated string in DS:SI to console + lodsb + cmp al, 0x00 # NUL? + jz 4f + cmp al, 0x0d # Ignore CR + jz print_msg + cmp al, 0x0a # Handle LF + jnz 0f + push bx + mov ah, 0x03 + int 0x10 # Get Cursor pos + inc dh # Move to next line + mov dl, 0 # Set column to 0 + mov ah, 0x02 + int 0x10 # Set Cursor pos + pop bx + jmp print_msg +0: cmp al, 0x5c # '\' Escape sequence to set FG/BG color + jnz 3f + mov cl, 2 +1: lodsb + cmp al, 0x46 + jg print_msg # Invalid escape sequence + sub al, 0x30 # '0' + cmp al, 0x09 + jle 2f + sub al, 0x07 +2: shl bl, 4 + and al, 0x0f + or bl, al + dec cl + jnz 1b + jmp print_msg +3: mov cx, 0x0001 + mov ah, 0x09 + int 0x10 + push bx + xor bx, bx + mov ah, 0x03 + int 0x10 + inc dl + mov ah, 0x02 + int 0x10 + pop bx + jmp print_msg +4: ret + +/********************************************************************************/ +/* Data section */ +/********************************************************************************/ +err_msg: + .string "*** ERROR: THIS MEDIA CANNOT BOOT IN LEGACY MODE ***" + +/********************************************************************************/ +/* From offset 0x1b8, the MBR contains the partition table and signature data */ +/********************************************************************************/ + .org MBR_RESERVED +disk_signature: + .space 0x04 +filler: + .space 0x02 +partition_table: + .space PT_ENTRY_SIZE * PT_MAX +mbr_signature: + .word 0xAA55 diff --git a/res/mbr/msg.bin b/res/mbr/msg.bin new file mode 100644 index 0000000000000000000000000000000000000000..a6080668dbd4b2c09a7279fab70f75c6d4a68848 GIT binary patch literal 512 zcmZ?tcJ=>bc;Hvxg*^;4zx!_N7G~*YZ+^kj$$szwTi=20>^tfi&I%abHaxk@Ut$LX z8<2fz3)5MFEsncag`O2I(ro-4x~f$9`$0yA64^Av18D(i4ru{wSqxbmSpuEUwm6*? zp5J^#VBTxq9UM$MnHY98Fc{uGE4-VXp@`e?ThD>M8!xySUbF3cTJwUL;mhm4Yit-w z{B3wkzT0q>3IuOqJ}dC=*d_*$jnS_k+r*U0Y-Czv<5qt|$H0cOj!B38z+)B_evZTc zPL{rSeRwA$!xql70>Os2!5R-iw5>U;rKP3d8WiLoWTg<|;Tf#p>+0g^sNn4A=jR`y f;N%Y^JpB}WT-_a=BNcr8U0fA_8W=_b2wepL#)NXf literal 0 HcmV?d00001 diff --git a/res/mbr/msg.txt b/res/mbr/msg.txt new file mode 100644 index 00000000..0071ff74 --- /dev/null +++ b/res/mbr/msg.txt @@ -0,0 +1,11 @@ +**************************************** +*** ERROR: LEGACY BOOT OF UEFI MEDIA *** +**************************************** + +This drive can only boot in UEFI mode. +It can not boot in BIOS/Legacy mode. + +If you want to boot this drive in BIOS/Legacy mode, you +should recreate it in Rufus using the following settings: +* Partition scheme -> MBR +* Target system -> BIOS... diff --git a/res/mbr/readme.txt b/res/mbr/readme.txt index 3f8b8b7e..9d752947 100644 --- a/res/mbr/readme.txt +++ b/res/mbr/readme.txt @@ -14,11 +14,17 @@ a different ID according to the one found in its partition table entry. Eg. if the partition table lists the disk ID for the first partition as 0x81, then it will be swapped for 0x80. +An additional MBR (msg.S) also exists in this directory, that can be used to +display an ASCII message contained in the sectors directly following the MBR. +This can be used, for instance, to display a notice for media that cannot be +booted in BIOS/Legacy mode. + # 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. +also provided for your convenience. If you have the Bochs emulator installed, +you can also invoke 'make test' to test the MBR with Bochs. # Primer diff --git a/src/rufus.rc b/src/rufus.rc index 2ef072b3..b4dd5358 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.9.1617" +CAPTION "Rufus 3.9.1618" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -394,8 +394,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,1617,0 - PRODUCTVERSION 3,9,1617,0 + FILEVERSION 3,9,1618,0 + PRODUCTVERSION 3,9,1618,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -413,13 +413,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.9.1617" + VALUE "FileVersion", "3.9.1618" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.9.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.9.1617" + VALUE "ProductVersion", "3.9.1618" END END BLOCK "VarFileInfo"