[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
This commit is contained in:
Pete Batard 2020-02-19 14:22:14 +00:00
parent b8579c04da
commit bfbb9d2ed5
No known key found for this signature in database
GPG Key ID: 38E0CF5E69EDD671
9 changed files with 325 additions and 122 deletions

View File

@ -17,23 +17,23 @@
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
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

58
res/mbr/bochsrc.bxrc Normal file
View File

@ -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

View File

@ -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 <pete@akeo.ie> */
/* */
/* 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 <http://www.gnu.org/licenses/>. */
/* */
/********************************************************************************/
/********************************************************************************/
/* 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

Binary file not shown.

220
res/mbr/msg.S Normal file
View File

@ -0,0 +1,220 @@
/********************************************************************************/
/* MSG - A protective MBR that displays an ASCII message located in the */
/* following sectors. */
/* */
/* Copyright (c) 2019-2020 Pete Batard <pete@akeo.ie> */
/* */
/* 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 <http://www.gnu.org/licenses/>. */
/* */
/********************************************************************************/
/********************************************************************************/
/* 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

BIN
res/mbr/msg.bin Normal file

Binary file not shown.

11
res/mbr/msg.txt Normal file
View File

@ -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...

View File

@ -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

View File

@ -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"