1
0
Fork 0
mirror of https://gitlab.com/bztsrc/bootboot.git synced 2023-02-13 20:54:32 -05:00

Support for El Torito CDROM boot

This commit is contained in:
bzt 2018-07-24 00:10:35 +02:00
parent 7fe5e32477
commit 9d7e7ff406
13 changed files with 138 additions and 73 deletions

View file

@ -7,9 +7,9 @@ I provide pre-compiled images ready for use.
Standard GNU toolchain and a few files from gnuefi (included).
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (76k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (76k)
2. *x86_64-bios* BIOS and Multiboot (GRUB) compatible, OBSOLETE loader.
2. *x86_64-bios* BIOS, Multiboot (GRUB) and El Torito (CDROM) compatible, OBSOLETE loader.
If you want to recompile this, you'll need fasm (not included).
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bytes, works as MBR and VBR too), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (8k)
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bytes, works as MBR, VBR and CDROM boot record too), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (8k, loaded by boot.bin, also BBS Expansion ROM and Multiboot compliant)
3. *aarch64-rpi* ARMv8 boot loader for Raspberry Pi 3
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (27k)
@ -29,7 +29,7 @@ The protocol describes how to boot an ELF64 or PE32+ executable inside an initia
into clean 64 bit mode, without using any configuration or even knowing the file system of initrd.
On [BIOS](https://gitlab.com/bztsrc/bootboot/tree/master/x86_64-bios) based systems, the same image can be loaded via
Multiboot, chainload from MBR or VBR (GPT hybrid booting) or run as a BIOS Expansion ROM
Multiboot, chainload from MBR, VBR (GPT hybrid booting) and CDROM boot record, or run as a BIOS Expansion ROM
(so not only the ramdisk can be in ROM, but the loader as well).
On [UEFI machines](https://gitlab.com/bztsrc/bootboot/tree/master/x86_64-efi), it is a standard EFI OS Loader application.
@ -45,7 +45,7 @@ as if it were a monolitic kernel. And you can use your own file system for the i
Note: BOOTBOOT is not a boot manager, it's a boot loader protocol. If you want an interactive boot menu, you should
integrate that *before* a BOOTBOOT compatible loader is called. Like GRUB chainloading boot.bin (or loading bootboot.bin as a
kernel) or adding bootboot.efi to UEFI Boot Manager's menu for example.
multiboot "kernel" and initrd as a module) or adding bootboot.efi to UEFI Boot Manager's menu for example.
Licence
-------
@ -105,7 +105,7 @@ Glossary
* _initrd_: initial [ramdisk image](https://gitlab.com/bztsrc/bootboot/blob/master/README.md#installation)
(probably in ROM or flash, or on a GPT boot partition at BOOTBOOT\INITRD, or it can occupy the whole partition, or can be loaded
over the network). It's format and whereabouts are not specified (the good part :-) ) and can be optionally gzip compressed.
over the network or as a GRUB module). It's format and whereabouts are not specified (the good part :-) ) and can be optionally gzip compressed.
* _loader_: a native executable on the boot partition or in ROM. For multi-bootable disks
more loader implementations can co-exists.
@ -354,11 +354,21 @@ Either the disk does not have a GPT, or there's no EFI System Partition nor any
partition on it. Or the FAT file system is found but inconsistent, or doesn't have a BOOTBOOT directory.
```
BOOTBOOT-PANIC: INITRD not found
BOOTBOOT-PANIC: Not 2048 sector aligned
```
The loader could not find the initial ramdisk image on the boot partition. This message will be shown
even if you specify an alternative initrd file on EFI command line.
This error is only shown by bootboot.bin (and not by bootboot.efi or bootboot.img) and only when
booted from CDROM in El Torito "no emulation" mode, and the boot partition file system's
root directory is not 2048 bytes aligned or the cluster size is not multiple of 2048
bytes. For FAT16 it depends on FAT table size and therefore on file system size. If you
see this message, increase the number of hidden sectors in BPB by 2. FAT32 file systems are
not affected.
```
BOOTBOOT-PANIC: Initrd not found
```
The loader could not find the initial ramdisk image on the boot partition.
```
BOOTBOOT-PANIC: Kernel not found in initrd

View file

@ -1197,7 +1197,7 @@ diskerr:
}
gotinitrd:
if(initrd.ptr==NULL || initrd.size==0) {
puts("BOOTBOOT-PANIC: INITRD not found\n");
puts("BOOTBOOT-PANIC: Initrd not found\n");
goto error;
}
#if INITRD_DEBUG

BIN
boot.bin

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -5,7 +5,7 @@ See [BOOTBOOT Protocol](https://gitlab.com/bztsrc/bootboot) for common details.
On [BIOS](http://www.scs.stanford.edu/05au-cs240c/lab/specsbbs101.pdf) based systems, the same image can be loaded via
[Multiboot](https://www.gnu.org/software/grub/manual/multiboot/multiboot.html),
chainload from MBR or VBR (GPT hybrid booting via __boot.bin__) or run as a BIOS Expansion ROM
chainload from MBR, VBR (GPT hybrid booting) or from CDROM boot record via __boot.bin__, or run as a BIOS Expansion ROM
(so not only the ramdisk can be in ROM, but the loader as well).
Machine state
@ -16,16 +16,16 @@ IRQs masked. GDT unspecified, but valid, IDT unset. Code is running in superviso
Installation
------------
1. *BIOS disk*: copy __bootboot.bin__ to **_FS0:\BOOTBOOT\LOADER_**. You can place it inside your INITRD partition
1. *BIOS disk / cdrom*: copy __bootboot.bin__ to **_FS0:\BOOTBOOT\LOADER_**. You can place it inside your INITRD partition
or outside of partition area as well (with `dd conv=notrunc oseek=x`). Finally install __boot.bin__ in the
master boot record (or in volume boot record if you have a boot manager), saving bootboot.bin's first sector's
LBA number in a dword at 0x1B0. The [mkboot](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-bios/mkboot.c)
El Torito Boot catalog with "no emulation" or in Master Boot Record (or in Volume Boot Record if you have a boot manager),
saving bootboot.bin's first sector's LBA number in a dword at 0x1B0. The [mkboot](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-bios/mkboot.c)
utility will do that for you.
2. *BIOS ROM*: install __bootboot.bin__ in a **_BIOS Expansion ROM_**.
3. *GRUB*: specify __bootboot.bin__ as a Multiboot "kernel" in grub.cfg, or you can also chainload __boot.bin__. You can load
the initrd and the environment file as modules, if not given, they will be loaded from disk as usual. Example:
the initrd and the environment file as modules (in this order). If no modules given, they will be loaded from disk as usual. Example:
```
menuentry "MyKernel" {

View file

@ -24,7 +24,8 @@
;* DEALINGS IN THE SOFTWARE.
;*
;* This file is part of the BOOTBOOT Protocol package.
;* @brief 1nd stage loader, compatible with BIOS boot specification
;* @brief Stage1 loader, compatible with BIOS boot specification and
;* El Torito CD-ROM boot in "no emulation" mode
;*
;*********************************************************************
@ -75,7 +76,7 @@ bootboot_record:
;skip BPB area so that we can use this
;boot code on a FAT volume if needed
db 05Ah-($-$$) dup 0
.skipid: ;relocate our code to offset 600h
.skipid: ;relocate our code to offset 0h:600h
cli
xor ax, ax
mov ss, ax
@ -97,22 +98,23 @@ bootboot_record:
;and copy ourselves to 600h
mov cx, 100h
repnz movsw
;have to clear ds, because cs is set to 7c0 when booted from El Torito
push es
pop ds
jmp 0:.start
.start: ;save boot drive code
mov byte [drive], dl
;initialize lba packet
mov byte [lbapacket.size], 16
mov byte [lbapacket.count], 58
mov byte [lbapacket.addr0+1], 08h ;to address 800h
;check for lba presistance - floppy not supported any more
;we use pendrive as removable media for a long time
cmp dl, byte 80h
jl .nolba
cmp dl, byte 84h
jae .nostage2err
.notfloppy: mov ah, byte 41h
mov bx, word 55AAh
clc
int 13h
jc .nolba
cmp bx, word 0AA55h
@ -122,15 +124,42 @@ bootboot_record:
.nolba: mov si, lbanotf
jmp diefunc
.lbaok: ;try to load stage2 - it's a continous area on disk
;started at given sector with maximum size of 7400h bytes
;started at given sector with maximum size of 7000h bytes
mov si, stage2_addr
mov di, lbapacket.sect0
push bx
push di
;set up for hard-drive
movsw
movsw
movsw
movsw
call loadsectorfunc
mov byte [lbapacket.count], 56
;query cdrom status to see if it's a cdrom
mov ax, word 4B01h
mov dl, byte [drive]
mov si, spc_packet
mov byte [si], 13h
mov byte [si+2], 0h ;clear drive number
clc
int 13h
pop di
jc @f
;some buggy BIOSes (like bochs') fail to set carry flag and ax properly
cmp byte [si+2], 0h
jz @f
;lba=lba/4
clc
rcr word [di+2], 1
rcr word [di], 1
clc
rcr word [di+2], 1
rcr word [di], 1
mov byte [lbapacket.count], 14
;load sectors
@@: mov ah, byte 42h
mov dl, byte [drive]
mov si, lba_packet
int 13h
pop bx
;do we have a 2nd stage loader?
.chk: cmp word [ldr.header], bx
@ -138,15 +167,14 @@ bootboot_record:
cmp byte [ldr.header+3], 0E9h
jne .nostage2
;invoke stage2 real mode code
print okay
mov ax, [ldr.executor]
add ax, ldr.executor+3
jmp ax
.nostage2: ;try to load stage2 from a RAID mirror
inc byte [drive]
cmp byte [drive], 84h
jl .lbaok
cmp byte [drive], 8Fh
jle .lbaok
.nostage2err:
mov si, stage2notf
;fall into the diefunc code
@ -168,18 +196,6 @@ diefunc:
out 64h, al
jmp far 0FFFFh:0 ;invoke BIOS POST routine
;loads an LBA sector
loadsectorfunc:
push bx
push si
mov ah, byte 42h
mov dl, byte [drive]
mov si, lba_packet
int 13h
pop si
pop bx
ret
;ds:si zero terminated string to write
printfunc:
lodsb
@ -199,9 +215,10 @@ panic: db "-PANIC: ",0
lbanotf: db "LBA support",0
stage2notf: db "FS0:\BOOTBOOT\LOADER",0
found: db " not found",10,13,0
okay: db "Booting LOADER...",10,13,0
drive: db 0
lba_packet: db 01B0h-($-$$) dup 0
lba_packet: db 16 dup 0
spc_packet: db 13h dup 0
db 01B0h-($-$$) dup 0
;right before the partition table some data
stage2_addr:dd 0FFFFFFFFh,0 ;1B0h 2nd stage loader address

View file

@ -24,16 +24,16 @@
;* DEALINGS IN THE SOFTWARE.
;*
;* This file is part of the BOOTBOOT Protocol package.
;* @brief Booting code for BIOS and MultiBoot
;* @brief Booting code for BIOS, MultiBoot and El Torito
;*
;* 2nd stage loader, compatible with GRUB and
;* BIOS boot specification 1.0.1 too (even expansion ROM).
;* Stage2 loader, compatible with GRUB and BIOS boot specification
;* 1.0.1 (even expansion ROM) and El Torito "no emulation" CDROM boot.
;*
;* memory occupied: 800-7C00
;*
;* Memory map
;* 0h - 600h reserved for the system
;* 600h - 800h stage1 (MBR)
;* 600h - 800h stage1 (MBR/VBR, boot.bin)
;* 800h - 6C00h stage2 (this)
;* 6C00h - 7C00h stack
;* 8000h - 9000h bootboot structure
@ -420,6 +420,7 @@ getmemmap:
repnz stosd
cmp byte [hasinitrd], 0
jnz @f
mov dword [9000h], eax
mov dword [bootboot.initrd_ptr], eax
mov dword [bootboot.initrd_size], eax
@@: mov dword [bootboot.initrd_ptr+4], eax
@ -763,19 +764,54 @@ prot_realmodefunc:
prot_readsectorfunc:
push eax
push ecx
push edx
push esi
push edi
;load 8 sectors (1 page) in low memory
;load 8 sectors (1 page) or more in low memory
mov dword [lbapacket.sect0], eax
mov dword [lbapacket.sect1], edx
mov dword [lbapacket.addr], 0A000h
prot_realmode
mov ah, byte 42h
;try all drives from bootdev-8F to support RAID mirror
mov dl, byte [bootdev]
mov esi, lbapacket
mov byte [readdev], dl
.again: mov ax, word [lbapacket.count]
mov word [origcount], ax
;query cdrom status to see if it's a cdrom
mov ax, word 4B01h
mov dl, byte [readdev]
mov esi, spc_packet
mov byte [si], 13h
mov byte [si+2], 0h ;clear drive number
clc
int 13h
xor ebx, ebx
jc @f
;some buggy BIOSes (like bochs') fail to set carry flag and ax properly
cmp byte [si+2], 0h
jz @f
;use 2048 byte sectors instead of 512 if it's a cdrom
mov al, byte [lbapacket.sect0]
and al, 011b
or al, al
jz .cdok
;this should never happen.
; - GPT is loaded from PMBR, from LBA 0 (%4==0)
; - ESP is at LBA 128 (%4==0)
; - root dir is at LBA 172 (%4==0) for FAT16, and it's cluster aligned for FAT32
; - cluster size is multiple of 4 sectors
mov si, notcdsect
jmp real_diefunc
.cdok: shr dword [lbapacket.sect0], 2
add word [lbapacket.count], 3
shr word [lbapacket.count], 2
mov byte [iscdrom], 1
@@: mov dl, byte [readdev]
inc byte [readdev]
mov ah, byte 42h
mov esi, lbapacket
clc
int 13h
jnc @f
cmp byte [readdev], 08Fh
jle .again
@@: xor ebx, ebx
mov bl, ah
real_protmode
pop edi
@ -785,12 +821,11 @@ prot_readsectorfunc:
;and copy to addr where it wanted to be (maybe in high memory)
mov esi, dword [lbapacket.addr]
xor ecx, ecx
mov cx, word [lbapacket.count]
mov cx, word [origcount]
shl ecx, 7
repnz movsd
pop edi
@@: pop esi
pop edx
pop ecx
pop eax
ret
@ -880,9 +915,14 @@ protmode_start:
; read GPT
.getgpt: xor eax, eax
xor edx, edx
xor edi, edi
prot_readsector
if DEBUG eq 1
cmp byte [iscdrom], 0
jz @f
DBG32 dbg_cdrom
@@:
end if
mov esi, 0A000h+512
cmp dword [esi], 'EFI '
je @f
@ -967,7 +1007,6 @@ protmode_start:
; load INITRD from partition
dec ecx
shr ecx, 12
xor edx, edx
mov edi, dword [bootboot.initrd_ptr]
@@: add edi, 4096
prot_readsector
@ -1044,7 +1083,6 @@ protmode_start:
;load root directory
mov eax, dword [root_sec]
xor edx, edx
mov edi, dword [bootboot.initrd_ptr]
prot_readsector
@ -1072,15 +1110,12 @@ protmode_start:
@@: mov ax, word [esi + fatdir.cl]
;sec = (cluster-2)*secPerCluster+data_sec
sub eax, 2
xor edx, edx
mov ebx, dword [clu_sec]
mul ebx
add eax, dword [data_sec]
mov edi, dword [bootboot.initrd_ptr]
prot_readsector
mov dword [9000h], 0
;look for CONFIG and INITRD
mov esi, edi
mov ecx, 255
@ -1115,7 +1150,6 @@ protmode_start:
.nextcfg: push eax
;sec = (cluster-2)*secPerCluster+data_sec
sub eax, 2
xor edx, edx
mov ebx, dword [clu_sec]
mul ebx
shl ebx, 9
@ -1187,7 +1221,6 @@ protmode_start:
.nextclu: push eax
;sec = (cluster-2)*secPerCluster+data_sec
sub eax, 2
xor edx, edx
mov ebx, dword [clu_sec]
mov word [lbapacket.count], bx
mul ebx
@ -1894,9 +1927,18 @@ GDT_value: dw $-GDT_table
dd GDT_table
dd 0,0
align 16
lbapacket: ;lba packet for BIOS
.size: dw 10h
.count: dw 8
.addr: dd 0A000h
.sect0: dd 0
.sect1: dd 0
spc_packet: db 18h dup 0
entrypoint: dq 0
core_ptr: dd 0
core_len: dd 0
reqwidth: dd 1024
reqheight: dd 768
ebdaptr: dd 0
hw_stack: dd 0
bpb_sec: dd 0 ;ESP's first sector
@ -1906,17 +1948,11 @@ clu_sec: dd 0 ;sector per cluster
gpt_ptr: dd 0
gpt_num: dd 0
gpt_ent: dd 0
lbapacket: ;lba packet for BIOS
.size: dw 10h
.count: dw 8
.addr: dd 0A000h
.sect0: dd 0
.sect1: dd 0
.flataddr: dd 0,0
reqwidth: dd 1024
reqheight: dd 768
origcount: dw 0
bootdev: db 0
readdev: db 0
hasinitrd: db 0
iscdrom: db 0
fattype: db 0
vbememsize: dw 0
bkp: dd ' '
@ -1926,6 +1962,7 @@ dbg_A20 db " * Enabling A20",10,13,0
dbg_mem db " * E820 Memory Map",10,13,0
dbg_systab db " * System tables",10,13,0
dbg_time db " * System time",10,13,0
dbg_cdrom db " * Detected CDROM boot",10,13,0
dbg_env db " * Environment",10,13,0
dbg_initrd db " * Initrd loaded",10,13,0
dbg_gzinitrd db " * Gzip compressed initrd",10,13,0
@ -1944,12 +1981,13 @@ nogzmem: db "Inflating: "
noenmem: db "Not enough memory",0
noacpi: db "ACPI not found",0
nogpt: db "No boot partition",0
nord: db "INITRD not found",0
nord: db "Initrd not found",0
nolib: db "/sys not found in initrd",0
nocore: db "Kernel not found in initrd",0
badcore: db "Kernel is not a valid executable",0
novbe: db "VESA VBE error, no framebuffer",0
nogzip: db "Unable to uncompress",0
notcdsect: db "Not 2048 sector aligned",0
cfgfile: db "sys/config",0,0,0
kernel: db "sys/core"
db (128-($-kernel)) dup 0

View file

@ -25,7 +25,7 @@
*
* This file is part of the BOOTBOOT Protocol package.
* @brief Little tool to install boot.bin in MBR or VBR
*
*
*/
#include <stdio.h>

View file

@ -1071,6 +1071,6 @@ get_memory_map:
"retq"
: : "a"(entrypoint): "memory" );
}
return report(status,L"INITRD not found");
return report(status,L"Initrd not found");
}