Bye bye memtest.bin and memtest.efi, long live mt86plus

With the efi binary providing the BIOS floppy loading functionality,
there is no need to support separate memtest.bin file any longer.

Remove memtest.bin from {build32,build64}/Makefile, replace memtest.bin
amd memtest.efi with mt86plus eveywhere to avoid confusion with
other memtests.

Also, unify build32/Makefile and build64/Makefile by removing
unnecessary differences between them, like extra spaces or
different OBJS order.

Finally, update README.md, HOW_TO_DEBUG_WITH_GDB.md and other
places that had a reference to memtest.{bin,efi}. Note that for
debug_memtest.sh, mt86plus.efi is used.
This commit is contained in:
01e3 2024-08-11 16:21:32 -07:00
parent e88374f289
commit 51d6faf1d1
9 changed files with 74 additions and 846 deletions

View File

@ -67,20 +67,18 @@ using the GNU toolchain and the ELF file format. The tools required are:
* xorrisofs (optional)
To build a 32-bit image, change directory into the `build32` directory and
type `make`. The result is a `memtest.bin` binary image file which can be
booted directly by a legacy BIOS (in floppy mode) or by an intermediate
bootloader using the Linux 16-bit boot protocol and a `memtest.efi` binary
image file which can be booted directly by a 32-bit UEFI BIOS. Either image
can be booted by an intermediate bootloader using the Linux 32-bit or 32-bit
EFI handover boot protocols.
type `make`. The result is a `mt86plus` binary image file which can be
booted directly by a 32-bit UEFI BIOS (if named mt86plus.efi), by a legacy
BIOS (in floppy mode) or by an intermediate bootloader using the Linux 16-bit
boot protocol. The image can be also booted by an intermediate bootloader
using the Linux 32-bit or 32-bit EFI handover boot protocols.
To build a 64-bit image, change directory into the `build64` directory and
type `make`. The result is a `memtest.bin` binary image file which can be
booted directly by a legacy BIOS (in floppy mode) or by an intermediate
bootloader using the Linux 16-bit boot protocol and a `memtest.efi` binary
image file which can be booted directly by a 64-bit UEFI BIOS. Either image
can be booted by an intermediate bootloader using the Linux 32-bit, 64-bit,
or 64-bit EFI handover boot protocols.
type `make`. The result is a `mt86plus` binary image file which can be
booted directly by a 64-bit UEFI BIOS (if named mt86plus.efi), by a legacy
BIOS (in floppy mode) or by an intermediate bootloader using the Linux 16-bit
boot protocol. The image can be also booted by an intermediate bootloader
using the Linux 32-bit, 64-bit, or 64-bit EFI handover boot protocols.
In either case, to build an ISO image that can be used to create a bootable
CD, DVD, or USB Flash drive, type `make iso`, The result is a `memtest.iso`
@ -92,16 +90,16 @@ Note that when writing to a USB Flash drive, the ISO image must be written
directly ('dumped') to the raw device, either by using the `dd` command or
by using a utility that provides the same functionality.
When using an intermediate bootloader, either the `memtest.bin` file or the
`memtest.efi` file should be stored in a disk partition the bootloader can
access, and the bootloader configuration should be updated to boot from
that file as if it were a Linux kernel with no initial RAM disk. Several
boot command line options are recognised, as described below. If using the
16-bit boot protocol, Memtest86+ will use the display in text mode (640x400).
If using the 32-bit or 64-bit boot protocols, Memtest86+ will use the display
in either text mode or graphics mode, as specified in the `boot_params` struct
passed to it by the bootloader. If in graphics mode, the supplied framebuffer
must be at least 640x400 pixels; if larger, the display will be centred. If
When using an intermediate bootloader, `mt86plus` file should be stored
in a disk partition the bootloader can access, and the bootloader
configuration should be updated to boot from that file as if it were a Linux
kernel with no initial RAM disk. Several boot command line options are
recognised, as described below. If using the 16-bit boot protocol, Memtest86+
will use the display in text mode (640x400). If using the 32-bit or 64-bit
boot protocols, Memtest86+ will use the display in either text mode or
graphics mode, as specified in the `boot_params` struct passed to it by
the bootloader. If in graphics mode, the supplied framebuffer must be
at least 640x400 pixels; if larger, the display will be centred. If
the system was booted in UEFI mode, graphics mode must be used.
For test purposes, there is also an option to build an ISO image that uses

View File

@ -1,367 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
//
// bootsect.S supports booting directly from the BIOS or via an intermediate
// bootloader that supports the Linux boot protocol. If booted directly from
// the BIOS, it is loaded at address 0x7c00. It then loads setup.S immediately
// after itself (address 0x7e00) and the main program code at segment MAIN_SEG,
// using BIOS interrupts to read the data from disk. When using an intermediate
// bootloader, it provides the first few bytes of the Linux boot header (at the
// end of the boot sector), with the remainder of the header being provided by
// setup.S.
//
// Copyright (C) 2020 Martin Whitaker.
//
// Derived from memtest86+ bootsect.S:
//
// bootsect.s Copyright (C) 1991, 1992 Linus Torvalds
//
// 1-Jan-96 Modified by Chris Brady for use as a boot loader for MemTest-86.
#define __ASSEMBLY__
#include "boot.h"
.section ".bootsect", "ax", @progbits
.code16
# The BIOS boot entry point. This will be located at 0x7c00.
.globl boot
boot:
# Initialise the segment registers and the stack.
ljmp $BOOT_SEG, $init
init:
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $BOOT_STACK_TOP, %ax
movw %ax, %sp
# Many BIOS's default disk parameter tables will not recognize
# multi-sector reads beyond the maximum sector number specified
# in the default diskette parameter tables - this may mean 7
# sectors in some cases.
#
# Since single sector reads are slow and out of the question,
# we must take care of this by creating new parameter tables
# (for the first disk) in RAM. We will set the maximum sector
# count to 18 - the most we will encounter on an HD 1.44.
#
# High doesn't hurt. Low does.
#
# Segments are as follows:
# ds=es=ss=cs = BOOT_SEG,
# fs = 0, gs = parameter table segment
pushw $0
popw %fs
movw $0x78, %bx # fs:bx is parameter table address
lgs %fs:(%bx),%si # gs:si is source
movw %dx, %di # es:di is destination
movw $6, %cx # copy 12 bytes
cld
rep movsw %gs:(%si), (%di)
movw %dx, %di
movb $18, 4(%di) # patch sector count
movw %di, %fs:(%bx)
movw %es, %fs:2(%bx)
movw %cs, %ax
movw %ax, %fs
movw %ax, %gs
xorb %ah, %ah # reset FDC
xorb %dl, %dl
int $0x13
# Load the setup sectors directly after the boot block.
# Note that 'es' is already set up.
load_setup:
xorw %dx, %dx # drive 0, head 0
movw $0x0002, %cx # sector 2, track 0
movw $0x0200, %bx # address = 512, in BOOT_SEG
movw $(0x0200 + SETUP_SECS), %ax # service 2, nr of sectors
# (assume all on head 0, track 0)
int $0x13 # read it
jnc load_setup_done # ok - continue
pushw %ax # dump error code
call print_nl
movw %sp, %bp
call print_hex
popw %ax
xorb %dl, %dl # reset FDC
xorb %ah, %ah
int $0x13
jmp load_setup
load_setup_done:
# Get disk drive parameters, specifically number of sectors/track.
# It seems that there is no BIOS call to get the number of sectors.
# Guess 18 sectors if sector 18 can be read, 15 if sector 15 can be
# read. Otherwise guess 9.
xorw %dx, %dx # drive 0, head 0
movw $0x0012, %cx # sector 18, track 0
movw $BOOT_STACK, %bx # use the bottom of the stack (es = cs)
movw $0x0201, %ax # service 2, 1 sector
int $0x13
jnc got_sectors
movb $0x0f, %cl # sector 15
movw $0x0201, %ax # service 2, 1 sector
int $0x13
jnc got_sectors
movb $0x09, %cl
got_sectors:
movw %cx, %cs:sectors
movw $BOOT_SEG, %ax
movw %ax, %es
# Print a message.
movb $0x03, %ah # read cursor pos
xorb %bh, %bh
int $0x10
leaw boot_msg, %bp
movw $(boot_msg_end - boot_msg), %cx
movw $0x0007, %bx # page 0, attribute 7 (normal)
movw $0x1301, %ax # write string, move cursor
int $0x10
# Load the main test program.
movw $MAIN_SEG, %ax
movw %ax, %es
call read_it
call kill_motor
call turn_off_cursor
call print_nl
# Fix up the Linux boot header to indicate we've loaded into low memory.
movl $LOW_LOAD_ADDR, code32_start
# After that (everything loaded), we jump to the setup code loaded
# directly after the boot block.
ljmp $SETUP_SEG, $0
# This subroutine loads the system at address 0x10000, making sure no 64KB
# boundaries are crossed. We try to load it as fast as possible, loading
# whole tracks whenever we can.
#
# in: es - starting address segment (normally 0x1000)
#
sread: .word 1 + SETUP_SECS # sectors read of current track
head: .word 0 # current head
track: .word 0 # current track
read_it:
movw %es, %ax
testw $0x0fff, %ax
die:
jne die # es must be at 64kB boundary
xorw %bx,%bx # bx is starting address within segment
rp_read:
movw %es, %ax
subw $MAIN_SEG, %ax # have we loaded all yet?
cmpw sys_size, %ax
jbe ok1_read
ret
ok1_read:
movw %cs:sectors, %ax
subw sread, %ax
movw %ax, %cx
shlw $9, %cx
addw %bx, %cx
jnc ok2_read
je ok2_read
xorw %ax, %ax
subw %bx, %ax
shrw $9, %ax
ok2_read:
call read_track
movw %ax, %cx
add sread, %ax
cmpw %cs:sectors, %ax
jne ok3_read
movw $1, %ax
subw head, %ax
jne ok4_read
incw track
ok4_read:
movw %ax, head
xorw %ax, %ax
ok3_read:
movw %ax, sread
shlw $9, %cx
addw %cx, %bx
jnc rp_read
movw %es, %ax
addb $0x10, %ah
movw %ax, %es
xorw %bx, %bx
jmp rp_read
read_track:
pusha
pusha
movw $0xe2e, %ax # loading... message 2e = .
movw $7, %bx
int $0x10
popa
movw track, %dx
movw sread, %cx
incw %cx
movb %dl, %ch
movw head, %dx
movb %dl, %dh
andw $0x0100, %dx
movb $2, %ah
pushw %dx # save for error dump
pushw %cx
pushw %bx
pushw %ax
int $0x13
jc bad_rt
addw $8, %sp
popa
ret
bad_rt:
pushw %ax # save error code
call print_all # ah = error, al = read
xorb %ah, %ah
xorb %dl, %dl
int $0x13
addw $10, %sp
popa
jmp read_track
# This subroutine is for debugging purposes. It will print out all of the
# registers. The assumption is that this is called from a routine, with a
# stack frame like:
# dx
# cx
# bx
# ax
# err
# ret <- sp
print_all:
movw $5, %cx # error code + 4 registers
movw %sp, %bp
print_loop:
pushw %cx # save count left
call print_nl # nl for readability
cmpb 5, %cl # see if register name is needed
jae no_reg
movw $(0xe05 + 'A' - 1), %ax
subb %cl, %al
int $0x10
movb $'X', %al
int $0x10
movb $':', %al
int $0x10
no_reg:
addw $2, %bp # next register
call print_hex # print it
popw %cx
loop print_loop
ret
print_nl:
movw $0xe0d, %ax # CR
int $0x10
movb $0x0a, %al # LF
int $0x10
ret
# This subroutine is for debugging purposes, and prints the word pointed to
# by ss:bp in hexadecimal.
print_hex:
movw $4, %cx # 4 hex digits
movw (%bp), %dx # load word into dx
print_digit:
rolw $4, %dx # rotate so that lowest 4 bits are used
movb $0xe, %ah
movb %dl, %al # mask off so we have only next nibble
andb $0xf, %al
addb $'0', %al # convert to 0-based digit
cmpb $'9', %al # check for overflow
jbe good_digit
addb $('A' - '0' - 10), %al
good_digit:
int $0x10
loop print_digit
ret
# This subroutine turns off the floppy drive motor, so that we enter the
# kernel in a known state, and don't have to worry about it later.
kill_motor:
pushw %dx
movw $0x3f2, %dx
xorb %al, %al
outb %al, %dx
popw %dx
ret
# This subroutine turns off the text display cursor.
turn_off_cursor:
movb $0x01, %ah
movb $0x00, %bh
movw $0x2000, %cx
int $0x10
ret
# Local variables.
sectors:
.word 0
boot_msg:
.ascii "Loading Memtest86+"
boot_msg_end:
# Emulate the Linux boot header, to allow loading by intermediate boot loaders.
.org 497
setup_sects:
.byte SETUP_SECS
root_flags:
.word 0
sys_size:
.long _sys_size
ram_size:
.word 0
vid_mode:
.word 0
root_dev:
.word 0
boot_flag:
.word 0xAA55

View File

@ -9,8 +9,8 @@
// offset 0x1b0. The LBA value is assumed to be offset by 4, for compatibility
// with the xorrisofs --grub2-mbr option.
//
// The first 512B of the memtest binary image is not used, so either of the
// memtest.bin or memtest.efi images may be used.
// The first 512B of the memtest binary image is not used, so mt86plus image
// can be used.
//
// Copyright (C) 2020 Martin Whitaker.

View File

@ -1,395 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
//
// setup.S collects the memory map information from the BIOS, disables APM,
// enables A20, and performs the switch from real mode to protected mode
// before jumping to the main program entry point.
//
// The memory map information is stored in the 4KB block of memory immediately
// following the setup code. The layout of the information matches the Linux
// boot_params struct. A pointer to this block is passed to the main program,
// for compatiblity with the Linux 32-bit boot protocol.
//
// Copyright (C) 2020-2021 Martin Whitaker.
//
// Derived from memtest86+ setup.S and head.S:
//
// 1-Jan-96 Modified by Chris Brady for use as a boot/loader for memtest-86.
#define __ASSEMBLY__
#include "boot.h"
#include "build_version.h"
#define BOOT_PARAMS_START (SETUP_SECS * 512)
#define BOOT_PARAMS_END (BOOT_PARAMS_START + 4096)
.section ".setup", "ax", @progbits
.code16
# Emulate the Linux boot header, to allow loading by other boot loaders.
# Indicate that the main program code should be loaded in high memory.
# bootsect.S will fix up the values if we are booted directly from the BIOS.
.globl setup
setup:
jmp do_setup
header:
.ascii "HdrS"
version:
.word 0x020c
realmode_swtch:
.long 0
start_sys_seg:
.word 0x1000
kernel_version:
.word mt86plus_version-512
type_of_loader:
.byte 0
loadflags:
.byte 0x1 # LOADED_HIGH
setup_move_size:
.word 0
.globl code32_start
code32_start:
.long HIGH_LOAD_ADDR
ramdisk_image:
.long 0
ramdisk_size:
.long 0
bootsect_kludge:
.long 0
heap_end_ptr:
.word 0
ext_loader_ver:
.byte 0
ext_loader_type:
.byte 0
cmd_line_ptr:
.long 0
initrd_addr_max:
.long 0xffffffff
kernel_alignment:
.long 4096
relocatable_kernel:
.byte 0
min_alignment:
.byte 12
xload_flags:
#ifdef __x86_64__
.word 0x9 # XLF_KERNEL_64,XLF_EFI_HANDOVER_64
#else
.word 0x4 # XLF_EFI_HANDOVER_32
#endif
cmd_line_size:
.long 255
hardware_subarch:
.long 0
hardware_subarch_data:
.quad 0
payload_offset:
.long 0
payload_length:
.long 0
setup_data:
.quad 0
pref_address:
.quad HIGH_LOAD_ADDR
init_size:
.long _init_size
handover_offset:
.long 0x10
do_setup:
# Reload the segment registers, except for the stack.
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
# Get the memory map and disable APM.
call get_mem_info
call disable_apm
# Disable interrupts.
cli
movb $0x80, %al # disable NMI
outb %al, $0x70
# Enable A20.
# Try to switch using the fast A20 gate.
movw $0x92, %dx
inb %dx, %al
# Skip if it's unimplemented (read returns 0xff).
cmpb $0xff, %al
jz 0f
orb $0x02, %al # set the ALT_A20_GATE bit
andb $0xfe, %al # clear the INIT_NOW bit
outb %al, %dx
0:
# Use the keyboard controller method anyway.
call empty_8042
movb $0xd1, %al # send write command
outb %al, $0x64
call empty_8042
movb $0xdf, %al # A20 on
outb %al, $0x60
call empty_8042
# Set up a minimal GDT and IDT.
xorl %eax, %eax
movw %cs, %ax
shll $4, %eax
addl %eax, gdt_descr - setup + 2
lgdt gdt_descr - setup
lidt idt_descr - setup
# Load a pointer to the boot_params block into ESI.
xorl %esi, %esi
movw %cs, %si
shll $4, %esi
addl $BOOT_PARAMS_START, %esi
# Fix up the jump address.
movl (code32_start - setup), %eax
movl %eax, (jump - setup + 2)
# Copy code32_start to the boot_params struct.
movl %eax, (BOOT_PARAMS_START + 0x214)
# Copy cmd_line_ptr and cmd_line_size to the boot_params struct.
movl (cmd_line_ptr - setup), %eax
movl %eax, (BOOT_PARAMS_START + 0x228)
movl (cmd_line_size - setup), %eax
movl %eax, (BOOT_PARAMS_START + 0x238)
# Switch to protected mode.
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
jmp flush
flush:
# Reload the segment registers and jump to the main test program.
movw $KERNEL_DS, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw %ax, %fs
movw %ax, %gs
jump:
data32 ljmp $KERNEL_CS, $0
# This subroutine queries the BIOS to determine the system memory map
# and stores the results in the boot_params structure that we pass to
# the startup code.
#define SMAP 0x534d4150
get_mem_info:
push %ds
push %es
# Set DS and ES to point to the start of the boot_params structure.
movw %ds, %ax
addw $(BOOT_PARAMS_START >> 4), %ax
movw %ax, %ds
movw %ax, %es
# Zero the entire boot_params structure.
movw $0x0000, %di
movw $0x0400, %cx
xorl %eax, %eax
cld
rep stosl
# First try method E820. E820 returns memory classified into a whole
# bunch of different types, and allows memory holes and everything.
mem_e820:
movw $E820_MAP, %di # destination pointer
xorl %ebx, %ebx # continuation counter
loop_e820:
movl $0x0000e820, %eax # e820, upper word zeroed
movl $SMAP, %edx # ASCII 'SMAP'
movl $20, %ecx # size of the e820 record
int $0x15 # make the call
jc done_e820 # bail out if it fails
cmpl $SMAP, %eax # check the return is 'SMAP'
jne done_e820 # bail out if it fails
incb (E820_ENTRIES)
addw $E820_ENTRY_SIZE, %di
movb (E820_ENTRIES), %al # check for table full
cmpb $E820_MAP_SIZE, %al
je done_e820
cmpl $0, %ebx # any more entries?
jne loop_e820
done_e820:
cmpb $0, (E820_ENTRIES)
jnz get_mem_done
# Next try method E801.
mem_e801:
stc # Fix to work around buggy BIOSs
xorw %cx,%cx # which don't clear/set carry on
xorw %dx,%dx # pass/error of e801h memory size
# call or merely pass cx,dx through
# without changing them.
movw $0xe801, %ax
int $0x15
jc mem_88
cmpw $0x0, %cx # Kludge to handle BIOSes which
jne 0f # report their extended memory in
cmpw $0x0, %dx # AX/BX rather than CX/DX. The spec
jne 0f # I have read seems to indicate that
movw %ax, %cx # AX/BX are more reasonable anyway.
movw %bx, %dx
0:
jmp fake_e820
# Finally try method 88.
mem_88:
movb $0x88, %ah
int $0x15
movw %ax, %cx
movw $0, %dx
fake_e820:
# Write entry for memory below 1MB.
movl $0x0, E820_ADDR(%di)
movl $0xa0000, E820_SIZE(%di)
movl $1, E820_TYPE(%di)
incb (E820_ENTRIES)
addw $E820_ENTRY_SIZE, %di
# Write entry for memory between 1MB and 16MB.
andl $0xffff, %ecx # convert to 32-bits
jz 0f
shll $10, %ecx # convert to bytes
movl $0x100000, E820_ADDR(%di)
movl %ecx, E820_SIZE(%di)
movl $1, E820_TYPE(%di)
incb (E820_ENTRIES)
addw $E820_ENTRY_SIZE, %di
0:
# Write entry for memory above 16MB.
andl $0xffff, %edx # convert to 32-bits
jz 1f
shll $16, %edx # convert to bytes
movl $0x1000000, E820_ADDR(%di)
movl %edx, E820_SIZE(%di)
movl $1, E820_TYPE(%di)
incb (E820_ENTRIES)
addw $E820_ENTRY_SIZE, %di
1:
get_mem_done:
pop %es
pop %ds
ret
# This subroutine disables APM if it is present.
disable_apm:
movw $0x5300, %ax # APM BIOS installation check
xorw %bx, %bx
int $0x15
jc disable_apm_done # error -> no APM BIOS
cmpw $0x504d, %bx # check for "PM" signature
jne disable_apm_done # no signature -> no APM BIOS
movw $0x5304, %ax # Disconnect first just in case
xorw %bx, %bx
int $0x15 # ignore return code
movw $0x5301, %ax # Real Mode connect
xorw %bx, %bx
int $0x15
jc disable_apm_done # error
movw $0x5308, %ax # Disable APM
mov $0xffff, %bx
xorw %cx, %cx
int $0x15
disable_apm_done:
ret
# This subroutine checks that the keyboard command queue is empty (after
# emptying the output buffers). No timeout is used - if this hangs there
# is something wrong with the machine, and we probably couldn't proceed
# anyway.
empty_8042:
call delay
inb $0x64, %al # 8042 status port
cmpb $0xff, %al # skip if not implemented
jz empty_8042_ret
testb $1, %al # anything in the output buffer?
jz no_output
call delay
inb $0x60, %al # read it
jmp empty_8042
no_output:
testb $2, %al # is input buffer full?
jnz empty_8042 # yes - loop
empty_8042_ret:
ret
# This subroutine provides a short delay.
delay:
.word 0x00eb # jmp $+2
ret
# A minimal GDT and IDT.
.align 4
gdt:
.quad 0x0000000000000000 # NULL descriptor
.quad 0x0000000000000000 # not used
.quad 0x00c09a0000007fff # 128MB 32-bit code at 0x000000
.quad 0x00c0920000007fff # 128MB 32-bit code at 0x000000
gdt_end:
.word 0 # for alignment
gdt_descr:
.word gdt_end - gdt - 1 # gdt limit
.long gdt - setup # gdt base - relocated at run time
.word 0 # for alignment
idt_descr:
.word 0 # idt limit=0
.long 0 # idt base=0
mt86plus_version:
.ascii "Memtest86+ v" , MT_VERSION
.byte 0
# Pad to the declared size.
.org (SETUP_SECS*512)

View File

@ -83,7 +83,7 @@ APP_OBJS = app/badram.o \
OBJS = boot/startup.o boot/efisetup.o $(SYS_OBJS) $(IMC_OBJS) $(LIB_OBJS) $(TST_OBJS) $(APP_OBJS)
all: memtest.bin memtest.efi
all: mt86plus
check:
@if [ -z ${DEBUG} ]; then\
@ -91,7 +91,7 @@ check:
exit 1;\
fi
debug: check memtest.debug memtest.efi
debug: check memtest.debug mt86plus
-include boot/efisetup.d
-include $(subst .o,.d,$(SYS_OBJS))
@ -112,7 +112,7 @@ boot/%.o: ../boot/%.S ../boot/boot.h app/build_version.h
boot/efisetup.o: ../boot/efisetup.c
@mkdir -p boot
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
system/reloc.o: ../system/reloc32.c
@mkdir -p system
@ -120,15 +120,15 @@ system/reloc.o: ../system/reloc32.c
system/%.o: ../system/%.c
@mkdir -p system
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
system/imc/%.o: ../system/imc/%.c
@mkdir -p system/imc
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
lib/%.o: ../lib/%.c
@mkdir -p lib
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
tests/%.o: ../tests/%.c
@mkdir -p tests
@ -169,24 +169,20 @@ memtest.debug: memtest_shared
strip -R .eh_frame memtest_shared
strip -R .comment memtest_shared
memtest.bin: memtest_shared.bin boot/bootsect.o boot/setup.o ldscripts/memtest_bin.lds
mt86plus: memtest_shared.bin boot/header.o ldscripts/memtest_efi.lds
$(eval SIZES=$(shell size -B -d memtest_shared | grep memtest_shared))
$(LD) --defsym=_bss_size=$(word 3,$(SIZES)) -T ldscripts/memtest_bin.lds boot/bootsect.o boot/setup.o -b binary memtest_shared.bin -o memtest.bin
memtest.efi: memtest_shared.bin boot/header.o boot/setup.o ldscripts/memtest_efi.lds
$(eval SIZES=$(shell size -B -d memtest_shared | grep memtest_shared))
$(LD) --defsym=_bss_size=$(word 3,$(SIZES)) -T ldscripts/memtest_efi.lds boot/header.o -b binary memtest_shared.bin -o memtest.efi
$(LD) --defsym=_bss_size=$(word 3,$(SIZES)) -T ldscripts/memtest_efi.lds boot/header.o -b binary memtest_shared.bin -o mt86plus
memtest.mbr: memtest_shared.bin boot/mbr.o ldscripts/memtest_mbr.lds
$(LD) -T ldscripts/memtest_mbr.lds boot/mbr.o -b binary memtest_shared.bin -o memtest.mbr
floppy.img: memtest.bin
floppy.img: mt86plus
dd if=/dev/zero of=floppy.img bs=1474560 count=1
dd if=memtest.bin of=floppy.img bs=1474560 conv=notrunc
dd if=mt86plus of=floppy.img bs=1474560 conv=notrunc
esp.img: memtest.efi
esp.img: mt86plus
@mkdir -p iso/EFI/BOOT
cp memtest.efi iso/EFI/BOOT/bootia32.efi
cp mt86plus iso/EFI/BOOT/bootia32.efi
@rm -f esp.img
/sbin/mkdosfs -n MEMTEST-ESP -F12 -C esp.img 4096
mcopy -s -i esp.img iso/EFI ::
@ -202,7 +198,7 @@ memtest.iso: memtest.mbr floppy.img esp.img
iso: memtest.iso
clean:
rm -rf boot system lib tests app *.img *.iso memtest* iso grub-*
rm -rf boot system lib tests app *.img *.iso memtest* mt86plus iso grub-*
# grub-memtest.iso uses GRUB as an intermediate bootloader to allow Memtest86+
# to be started with the native USB keyboard drivers either enabled or disabled,
@ -237,9 +233,9 @@ grub-eltorito.img:
grub-bootia32.efi:
$(GRUB_MKIMAGE) --output $@ --prefix /EFI/BOOT/grub --format i386-efi $(GRUB_MODULES)
grub-esp.img: memtest.efi grub-bootia32.efi ../grub/${GRUB_CFG}-efi.cfg
grub-esp.img: mt86plus grub-bootia32.efi ../grub/${GRUB_CFG}-efi.cfg
@mkdir -p grub-iso/EFI/BOOT/grub/i386-efi grub-iso/EFI/BOOT/grub/fonts
cp memtest.efi grub-iso/EFI/BOOT/memtest
cp mt86plus grub-iso/EFI/BOOT/memtest
cp grub-bootia32.efi grub-iso/EFI/BOOT/bootia32.efi
cp ../grub/${GRUB_CFG}-efi.cfg grub-iso/EFI/BOOT/grub/grub.cfg
cp $(GRUB_FONT_DIR)/unicode.pf2 grub-iso/EFI/BOOT/grub/fonts/
@ -248,9 +244,9 @@ grub-esp.img: memtest.efi grub-bootia32.efi ../grub/${GRUB_CFG}-efi.cfg
/sbin/mkdosfs -n MT86P_ESP -F12 -C grub-esp.img 8192
mcopy -s -i grub-esp.img grub-iso/EFI ::
grub-memtest.iso: memtest.bin grub-eltorito.img ../grub/${GRUB_CFG}-legacy.cfg grub-esp.img
grub-memtest.iso: mt86plus grub-eltorito.img ../grub/${GRUB_CFG}-legacy.cfg grub-esp.img
@mkdir -p grub-iso/boot/grub/i386-pc grub-iso/boot/grub/fonts
cp memtest.bin grub-iso/boot/memtest
cp mt86plus grub-iso/boot/memtest
cp grub-eltorito.img grub-iso/boot/eltorito.img
cp ../grub/${GRUB_CFG}-legacy.cfg grub-iso/boot/grub/grub.cfg
cp $(GRUB_FONT_DIR)/unicode.pf2 grub-iso/boot/grub/fonts/

View File

@ -197,9 +197,9 @@ Prepare_Directory() {
exit 1
fi
# Copy memtest.efi to hda-contents
cp memtest.efi hda-contents/
cp memtest.efi hda-contents/EFI/boot/BOOT_IA32.efi
# Copy mt86plus to hda-contents
cp mt86plus hda-contents/mt86plus.efi
cp mt86plus hda-contents/EFI/boot/BOOT_IA32.efi
# Copy OVMF* files from /usr/share
if [ ! -f OVMF32_VARS.fd ] || [ ! -f OVMF32_CODE.fd ]; then

View File

@ -33,8 +33,8 @@ SYS_OBJS = system/acpi.o \
system/cpulocal.o \
system/ehci.o \
system/font.o \
system/hwctrl.o \
system/heap.o \
system/hwctrl.o \
system/hwquirks.o \
system/keyboard.o \
system/ohci.o \
@ -83,7 +83,7 @@ APP_OBJS = app/badram.o \
OBJS = boot/startup.o boot/efisetup.o $(SYS_OBJS) $(IMC_OBJS) $(LIB_OBJS) $(TST_OBJS) $(APP_OBJS)
all: memtest.bin memtest.efi
all: mt86plus
check:
@if [ -z ${DEBUG} ]; then\
@ -91,7 +91,7 @@ check:
exit 1;\
fi
debug: check memtest.debug memtest.efi
debug: check memtest.debug mt86plus
-include boot/efisetup.d
-include $(subst .o,.d,$(SYS_OBJS))
@ -112,15 +112,15 @@ boot/%.o: ../boot/%.S ../boot/boot.h app/build_version.h
boot/efisetup.o: ../boot/efisetup.c
@mkdir -p boot
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
system/reloc.o: ../system/reloc64.c
@mkdir -p system
$(CC) -c $(CFLAGS) -fno-strict-aliasing $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) -fno-strict-aliasing $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
system/%.o: ../system/%.c
@mkdir -p system
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
system/imc/%.o: ../system/imc/%.c
@mkdir -p system/imc
@ -128,15 +128,15 @@ system/imc/%.o: ../system/imc/%.c
lib/%.o: ../lib/%.c
@mkdir -p lib
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
tests/%.o: ../tests/%.c
@mkdir -p tests
$(CC) -c $(CFLAGS) $(OPT_FAST) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_FAST) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
app/%.o: ../app/%.c app/build_version.h
@mkdir -p app
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
$(CC) -c $(CFLAGS) $(OPT_SMALL) $(INC_DIRS) -o $@ $< -MMD -MP -MT $@ -MF $(@:.o=.d)
app/build_version.h: FORCE
@mkdir -p app
@ -169,24 +169,20 @@ memtest.debug: memtest_shared
strip -R .eh_frame memtest_shared
strip -R .comment memtest_shared
memtest.bin: memtest_shared.bin boot/bootsect.o boot/setup.o ldscripts/memtest_bin.lds
mt86plus: memtest_shared.bin boot/header.o ldscripts/memtest_efi.lds
$(eval SIZES=$(shell size -B -d memtest_shared | grep memtest_shared))
$(LD) --defsym=_bss_size=$(word 3,$(SIZES)) -T ldscripts/memtest_bin.lds boot/bootsect.o boot/setup.o -b binary memtest_shared.bin -o memtest.bin
memtest.efi: memtest_shared.bin boot/header.o boot/setup.o ldscripts/memtest_efi.lds
$(eval SIZES=$(shell size -B -d memtest_shared | grep memtest_shared))
$(LD) --defsym=_bss_size=$(word 3,$(SIZES)) -T ldscripts/memtest_efi.lds boot/header.o -b binary memtest_shared.bin -o memtest.efi
$(LD) --defsym=_bss_size=$(word 3,$(SIZES)) -T ldscripts/memtest_efi.lds boot/header.o -b binary memtest_shared.bin -o mt86plus
memtest.mbr: memtest_shared.bin boot/mbr.o ldscripts/memtest_mbr.lds
$(LD) -T ldscripts/memtest_mbr.lds boot/mbr.o -b binary memtest_shared.bin -o memtest.mbr
floppy.img: memtest.bin
floppy.img: mt86plus
dd if=/dev/zero of=floppy.img bs=1474560 count=1
dd if=memtest.bin of=floppy.img bs=1474560 conv=notrunc
dd if=mt86plus of=floppy.img bs=1474560 conv=notrunc
esp.img: memtest.efi
esp.img: mt86plus
@mkdir -p iso/EFI/BOOT
cp memtest.efi iso/EFI/BOOT/bootx64.efi
cp mt86plus iso/EFI/BOOT/bootx64.efi
@rm -f esp.img
/sbin/mkdosfs -n MEMTEST-ESP -F12 -C esp.img 4096
mcopy -s -i esp.img iso/EFI ::
@ -202,7 +198,7 @@ memtest.iso: memtest.mbr floppy.img esp.img
iso: memtest.iso
clean:
rm -rf boot system lib tests app *.img *.iso memtest* iso grub-*
rm -rf boot system lib tests app *.img *.iso memtest* mt86plus iso grub-*
# grub-memtest.iso uses GRUB as an intermediate bootloader to allow Memtest86+
# to be started with the native USB keyboard drivers either enabled or disabled,
@ -237,9 +233,9 @@ grub-eltorito.img:
grub-bootx64.efi:
$(GRUB_MKIMAGE) --output $@ --prefix /EFI/BOOT/grub --format x86_64-efi $(GRUB_MODULES)
grub-esp.img: memtest.efi grub-bootx64.efi ../grub/${GRUB_CFG}-efi.cfg
grub-esp.img: mt86plus grub-bootx64.efi ../grub/${GRUB_CFG}-efi.cfg
@mkdir -p grub-iso/EFI/BOOT/grub/x86_64-efi grub-iso/EFI/BOOT/grub/fonts
cp memtest.efi grub-iso/EFI/BOOT/memtest
cp mt86plus grub-iso/EFI/BOOT/memtest
cp grub-bootx64.efi grub-iso/EFI/BOOT/bootx64.efi
cp ../grub/${GRUB_CFG}-efi.cfg grub-iso/EFI/BOOT/grub/grub.cfg
cp $(GRUB_FONT_DIR)/unicode.pf2 grub-iso/EFI/BOOT/grub/fonts/
@ -248,9 +244,9 @@ grub-esp.img: memtest.efi grub-bootx64.efi ../grub/${GRUB_CFG}-efi.cfg
/sbin/mkdosfs -n MT86P_ESP -F12 -C grub-esp.img 8192
mcopy -s -i grub-esp.img grub-iso/EFI ::
grub-memtest.iso: memtest.bin grub-eltorito.img ../grub/${GRUB_CFG}-legacy.cfg grub-esp.img
grub-memtest.iso: mt86plus grub-eltorito.img ../grub/${GRUB_CFG}-legacy.cfg grub-esp.img
@mkdir -p grub-iso/boot/grub/i386-pc grub-iso/boot/grub/fonts
cp memtest.bin grub-iso/boot/memtest
cp mt86plus grub-iso/boot/memtest
cp grub-eltorito.img grub-iso/boot/eltorito.img
cp ../grub/${GRUB_CFG}-legacy.cfg grub-iso/boot/grub/grub.cfg
cp $(GRUB_FONT_DIR)/unicode.pf2 grub-iso/boot/grub/fonts/

View File

@ -199,9 +199,9 @@ Prepare_Directory() {
exit 1
fi
# Copy memtest.efi to hda-contents
cp memtest.efi hda-contents/
cp memtest.efi hda-contents/EFI/boot/BOOT_X64.efi
# Copy mt86plus to hda-contents
cp mt86plus hda-contents/mt86plus.efi
cp mt86plus hda-contents/EFI/boot/BOOT_X64.efi
# Copy OVMF* files from /usr/share
if [ ! -f OVMF.fd ] || [ ! -f OVMF_VARS.fd ] || [ ! -f OVMF_CODE.fd ]; then

View File

@ -1,4 +1,4 @@
# How to debug memtest.efi in QEMU with GDB
# How to debug mt86plus in QEMU with GDB
`debug_memtest.sh` is a script that allows memtest86plus developers to set up a debugging environment with GDB in QEMU.
It calls the `make debug` target of a modified Makefile to create an additional debug-symbol file called `memtest.debug`.
@ -28,7 +28,7 @@ This script will automatically be loaded when gdb starts.
* wait until UEFI-Shell is loaded
* type "fs0:" - Enter
* type "memtest.efi" - Enter
* type "mt86plus.efi" - Enter
### Inside GDB
@ -36,9 +36,9 @@ When GDB is running, it stops at the first breakpoint at main(). Feel free to ad
### Remarks - auto-boot memtest86+
In step **Navigate inside QEMU/UEFI**, you have to navigate to the directory which contains memtest.efi and manually launch it.
In step **Navigate inside QEMU/UEFI**, you have to navigate to the directory which contains mt86plus.efi and manually launch it.
If you want to automatically boot from memtest.efi, there is an additional step required to add memtest to the first place at the bootorder:
If you want to automatically boot from mt86plus.efi, there is an additional step required to add memtest to the first place at the bootorder:
When the UEFI Shell is running, type
`bcfg boot add 0 FS0:\EFI\boot\BOOT_X64.efi "memtest"`
@ -46,7 +46,7 @@ and confirm with Enter.
The directory "\EFI\boot" and the file "BOOT_X64.efi" are automatically
created by the debug-script.
When you run the script the next time, memtest.efi should run without
When you run the script the next time, mt86plus.efi should run without
previous user interaction.
!! But be careful when cleaning the directory by './debug_memtest.sh -c'. It also removes this setting.
@ -68,15 +68,15 @@ Both values are defined in `memtest86plus/boot/header.S`
* IMMUTABILITY OF ALL CONDITIONS
if you assume, that these values will never change during the development phase of memtest86plus AND memtest.efi is always loaded at this preferred address in qemu-system-x86_64 (which seems to be the case) then it is possible to hardcode the offset in the script (for the implementation see debug_memtest_simple.sh)
if you assume, that these values will never change during the development phase of memtest86plus AND mt86plus.efi is always loaded at this preferred address in qemu-system-x86_64 (which seems to be the case) then it is possible to hardcode the offset in the script (for the implementation see debug_memtest_simple.sh)
* ADAPTABILITY TO DEVELOPMENT CHANGES
if there is a chance, that these values WILL change during the development phase but memtest.efi is always loaded at this preferred address then the value can be read from header.S by the debug script just right before starting the debugging (for an example, see debug_memtest_full.sh)
if there is a chance, that these values WILL change during the development phase but mt86plus.efi is always loaded at this preferred address then the value can be read from header.S by the debug script just right before starting the debugging (for an example, see debug_memtest_full.sh)
* EXPECTED ERRATIC BEHAVIOUR OF QEMU
If it is expected that memtest.efi is NOT always loaded at the same address, it is inevitable to determine the actual loading address first. This approach comprises a DEBUG-build of OVMF.fd (which requires the cloning of the whole edk2-repository and manually build OVMF.fd). With this DEBUG-version of OVMF.fd it is possible to write the loading addresses of all modules into a debug.log.
If it is expected that mt86plus.efi is NOT always loaded at the same address, it is inevitable to determine the actual loading address first. This approach comprises a DEBUG-build of OVMF.fd (which requires the cloning of the whole edk2-repository and manually build OVMF.fd). With this DEBUG-version of OVMF.fd it is possible to write the loading addresses of all modules into a debug.log.
This proceeding has been tested successfully but is actually not implemented in one of the srcipts.
### Handle relocation of memtest
@ -94,4 +94,4 @@ TODO: Is it possible to deactivate relocation? E.g. by outcommenting some code o
* FOLLOW RELOCATION
If the position after relocation is expected to be always the same, then you can just load the symbol table twice. This is done in debug_memtest_simple.sh (the offsets are 0x201000 and 0x400000). If the locations can vary then the offsets must be determined dynamically ... todo: how?
If the position after relocation is expected to be always the same, then you can just load the symbol table twice. This is done in debug_memtest_simple.sh (the offsets are 0x201000 and 0x400000). If the locations can vary then the offsets must be determined dynamically ... todo: how?