Skip to content

Commit

Permalink
[boot] Cleanup boot sector code, add boot documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ghaerr committed Feb 18, 2022
1 parent 76a71a2 commit 99b4a05
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 40 deletions.
72 changes: 71 additions & 1 deletion Documentation/text/boot.txt
Expand Up @@ -148,9 +148,79 @@ ELKS "INITSEG" (setup data segment) offsets:
| 01F1 | 497 | byte | setup_sects | size in 512-byte sects | build.c
| 01F2 | 498 | word | ROOTFLAGS | UNUSED |
| 01F4 | 500 | word | syssize | kernel size in paras | build.c
| 01F6 | 502 | word | elks_flags | BLOB, BIOS_DRV | boot_sect.S
| 01F6 | 502 | byte | elks_flags | BLOB, BIOS_DRV | boot_sect.S
! 01F7 | 503 | byte | | UNUSED |
| 01F8 | 504 | word | RAMDISK | UNUSED |
| 01FA | 506 | word | SVGAMODE | UNUSED |
| 01FC | 508 | word | root_dev | BIOS drive or kdev_t | build.c,boot_sect.S
| 01FE | 510 | word | boot_flag | AA55h | boot_sect.S
+------+-----+------+-------------------+--------------------------+------------


ELKS memory at boot and detailed boot description

+Step ----------------- seg off linear size (size start) -------------------------------+
| interrupt vectors 0000:0000 00000 0400 (1024) @0
| BIOS data area 0040:0000 00400 0100 (256) @1024
|4 bootopts 0050:0000 00500 0100 (256) @1280 DEF_OPTSEG loaded by minix.o
|8 3rd setup data 0060:0000 00600 0200 (512) @1536 REL_INITSEG (copied by setup)
| ...
| disk track cache 0080:0000 00800 2400 (9216) @2K DMASEG
| ...
|3 1st kblob load addr 0100:0000 01000 2F00 (188K) @4K DEF_INIT/LOADSEG/ELKS_INITSEG
|5 1st setup exec addr 0120:0000 01200 0200 (512) @4.5K DEF_INIT+20
|9 2nd kernel load&exec 02D0:0000 2D000 2F00 (188K) @11K REL_SYSSEG (relocated by setup)
|1 1st boot exec addr 07C0:0000 07C00 0200 (512) @31K BOOTADDR (loaded by BIOS at boot)
| 0800:0000 08000 0000 (32K) @32K
| 1000:0000 10000 0000 @64K
|6 1st kernel load addr 1300:0000 13000 2F00 (188K) @76K DEF_SYSSEG (copied by setup)
| ...
| ...
|7 2nd setup exec addr 9000:0000 90000 00200 (512) @576K copied by setup
|2 2nd boot exec addr 9000:0000 90000 00200 (512) @576K ES=DS=SS=CS (tiny model) copied
! bios_sect disk buf 9000:0200 90200 00200 (512) @576.5K (FAT BPB or minix payload here)
| top of 640k ram A000:0000 A0000 A0000 @640K
+-------------------------------------------------------------------------------------------+

1 BIOS loads disk sector 1 (bios_sect.S) to 07C0:0000
2 bios_sect.S copies itself to high memory 9000:0000 (8000:0000 on QEMU)
bios_sect stack grows down from 9000:0000

MINIX bios_sect calls payload at 9000:0200 (minix_boot.S, tiny model CS=DS=SS)
bios_sect .text and .data is ~03F6, linked with minix_boot.o is 1K boot sector
payload .data (offset after .text and .rodata) starts around 9000:03F6 to 9000:1406
3 payload reads MINIX superblock/fs and loads /linux as blob to 0100:0000 (DEF_INIT)
4 payload reads MINIX superblock/fs and loads /bootopts sector to 0050:0000 (DEF_OPTSEG)
boot_sect saves elks_flags (and other?) to 0100:0000 (DEF_INIT, which is SETUP data seg)
set by boot_sect: elks_flags
set by build: setup_sect, syssize
5 boot_sect checks ELKS setup signature and jumps to setup code seg 0120:0000 (DEF_INIT+20)

FAT bios_sect reads FAT BPB within itself at 9000:0000 and loads FAT root dir at 9000:0200
boot_sect .text is ~01E2, .data starts at ~01f7, standalone size is 512 byte boot sector
3 boot_sect reads FAT root dir to load LINUX as blob to 0100:0000 (DEF_INIT)
(4) no room to load BOOTOPTS sector to 0050:0000 (DEF_OPTSEG)
boot_sect saves elks_flags (and other?) to 0100:0000 (DEF_INIT, which is SETUP data seg)
5 boot_sect checks ELKS setup signature and jumps to setup code seg 0120:0000 (DEF_INIT+20)
setup uses root dir at 9000:0200 and BPB at 9000:0000 to load BOOTOPTS sector to 0050:0000

6 setup CS at 0120:0000 (DEF_INIT+20) checks ELKS sig and copies kernel to 1300:0 (DEF_SYSSEG)
6+ FAT only - setup reads high mem root dir 9000:0200 to get BOOTOPTS cluster
uses high mem BPB at 9000:0000 for secs_per_cluster, etc
7 setup copies its code segment from 0120:0000 (DEF_INIT+2) to high memory 9000:0 (8000 qemu)
8 setup now at 9000:0000 copies its data seg from 0100:0 (DEF_INIT) to 0700:0 (REL_INITSEG)
9 setup copies&relocates kernel from 1300:0000 (DEF_SYSSEG) to 02D0:0000 (REL_SYSSEG)
DMASEG starts after 0700:0000 (REL_INITSEG) at 0900:0000 to 02D0:0000 (REL_SYSSEG)
9+ finally, setup jumps to kernel at 02D0:0000 (REL_SYSSEG)

Current kernel is 80K in size (=14000h)
Boot loader:
0100:0000 DEF_INIT @4K
+ 1400:0000 size of kernel (80K)
1500:0000 end of 80K kernel
3000:0000 max end of 188K kernel @192K
Setup.S:
1300:0000 DEF_SYSSEG @76K
+ 1400:0000 size of kernel (80K)
2700:0000 end of 80K kernel
4200:0000 max end of 188K kernel @264K
14 changes: 3 additions & 11 deletions bootblocks/boot_sect.S
Expand Up @@ -36,7 +36,6 @@
#endif

#define LOADSEG DEF_INITSEG
#define ELKS_INITSEG DEF_INITSEG

// Whether to try to do whole-track reads, or read one sector at a time
//
Expand Down Expand Up @@ -595,26 +594,19 @@ not_elks:
jmp _except

boot_it:
.if LOADSEG != ELKS_INITSEG
.error
.endif

// Signify that /linux was loaded as 1 blob
.if ((EF_AS_BLOB|EF_BIOS_DEV_NUM) & 0xff) == 0
orb $(EF_AS_BLOB|EF_BIOS_DEV_NUM)>>8,elks_flags+1
.else
orw $(EF_AS_BLOB|EF_BIOS_DEV_NUM),elks_flags
.endif
orb $(EF_AS_BLOB|EF_BIOS_DEV_NUM),elks_flags
mov %dx,root_dev
mov %cx,part_offset // save sector offset of booted partition
mov %bx,part_offset+2

RESTORE_DDPT

mov $ELKS_INITSEG,%ax
mov $LOADSEG,%ax
mov %ax,%ds
mov %ax,%es
ljmp $ELKS_INITSEG+0x20,$0
ljmp $LOADSEG+0x20,$0
#endif

//------------------------------------------------------------------------------
Expand Down
22 changes: 9 additions & 13 deletions bootblocks/boot_sect_fat.h
Expand Up @@ -213,7 +213,7 @@
shr %cl,%ax
add %bx,%ax

// Load the file as one single blob at ELKS_INITSEG:0
// Load the file as one single blob at LOADSEG:0
mov 0x1d(%si),%dx // File size divided by 0x100
#if defined(CONFIG_IMG_FD1232)
shr %dx
Expand All @@ -225,17 +225,17 @@
// #issuecomment-581034966), BIOS reads may reportedly fail if %es
// for read calls is not aligned to a large power of 2; to be on the
// safe side, rewrite 0x100:0 into something like 0:0x1000...)
mov $ELKS_INITSEG,%cx
mov $LOADSEG,%cx
mov %cx,%es
.if (ELKS_INITSEG & 0xff) == 0
mov $ELKS_INITSEG>>4,%ch
.if (LOADSEG & 0xff) == 0
mov $LOADSEG>>4,%ch
.else
mov $ELKS_INITSEG<<4,%cx
mov $LOADSEG<<4,%cx
.endif
.if (ELKS_INITSEG & 0xf000) == 0
.if (LOADSEG & 0xf000) == 0
xor %bx,%bx
.else
mov $ELKS_INITSEG&0xf000,%bx
mov $LOADSEG&0xf000,%bx
.endif
push %bx
call disk_read
Expand All @@ -260,15 +260,11 @@
push %es
pop %ds
// Signify that /linux was loaded as 1 blob
.if ((EF_AS_BLOB|EF_BIOS_DEV_NUM) & 0xff) == 0
orb $(EF_AS_BLOB|EF_BIOS_DEV_NUM)>>8,elks_flags+1
.else
orw $(EF_AS_BLOB|EF_BIOS_DEV_NUM),elks_flags
.endif
orb $(EF_AS_BLOB|EF_BIOS_DEV_NUM),elks_flags
mov %ax,root_dev
mov %cx,part_offset // save sector offset of booted partition
mov %si,part_offset+2
ljmp $ELKS_INITSEG+0x20,$0
ljmp $LOADSEG+0x20,$0

kernel_name:
.ascii "LINUX "
Expand Down
3 changes: 2 additions & 1 deletion elks/arch/i86/boot/bootsect.S
Expand Up @@ -565,7 +565,8 @@ root_flags:
syssize:
.word SYSSIZE
elks_flags:
.word ELKSFLAGS
.byte EF_NONE
.byte 0
ram_size:
.word RAMDISK
vid_mode:
Expand Down
9 changes: 3 additions & 6 deletions elks/arch/i86/boot/setup.S
Expand Up @@ -70,7 +70,8 @@
! 0x1f1: setup_sects byte in 512-byte sectors, written by build tool
! 0x1f2: ROOTFLAGS word UNUSED
! 0x1f4: syssize word in paragraphs, written by build tool
! 0x1f6: elks_flags word EF_xxx
! 0x1f6: elks_flags byte EF_xxx
! 0x1f7: byte UNUSED
! 0x1f8: RAMDISK word UNUSED
! 0x1fa: SVGA_MODE word UNUSED
! 0x1fc: root_dev word Either BIOS boot device or actual kdev_t ROOT_DEV
Expand Down Expand Up @@ -152,11 +153,7 @@ no_sig_mess: .ascii "No ELKS setup signature found ..."
chk_blob:
mov $INITSEG,%ax
mov %ax,%ds
.if (EF_AS_BLOB & 0xff) == 0
testb $(EF_AS_BLOB>>8),elks_flags+1
.else
testw $EF_AS_BLOB,elks_flags
.endif
testb $EF_AS_BLOB,elks_flags
jz no_blob
std // move backwards --- we are moving from a
// lower address to a higher one
Expand Down
9 changes: 3 additions & 6 deletions elks/include/linuxmt/boot.h
Expand Up @@ -17,13 +17,12 @@
#endif

/* ELKS flags */

#define EF_NONE 0
#define EF_AS_BLOB 0x8000 /* says that setup and kernel are
#define EF_AS_BLOB 0x01 /* says that setup and kernel are
loaded as one blob at SETUPSEG:0,
and setup may need to move kernel
to SYSSEG:0 */
#define EF_BIOS_DEV_NUM 0x4000 /* says that root_dev does not give
#define EF_BIOS_DEV_NUM 0x02 /* says that root_dev does not give
a <major, minor> block device
number, but only a BIOS drive
number (and possibly other
Expand All @@ -32,8 +31,6 @@
figure out the correct root
device */

#define ELKSFLAGS EF_NONE

/* If we are not building the (dummy) boot sector (elks/elks/arch/i86/boot/
{bootsect.S, netbootsect.S}) at the start of /linux, then define
constants giving the offsets of various fields within /linux.
Expand All @@ -53,7 +50,7 @@
#define elks_magic 0x1e6 /* long "ELKS" (45 4c 4b 53) checked by bootsect.S*/
#define setup_sects 0x1f1 /* byte 512-byte sectors used by setup.S*/
#define syssize 0x1f4 /* word paragraph kernel size used by setup.S*/
#define elks_flags 0x1f6 /* word 16-bit ELKS flags, BLOB and BIOS_DRV*/
#define elks_flags 0x1f6 /* byte ELKS flags, BLOB and BIOS_DRV*/
#define root_dev 0x1fc /* word BIOS drive or kdev_t ROOT_DEV*/
#define boot_flag 0x1fe /* word constant AA55h*/
#endif
Expand Down
4 changes: 2 additions & 2 deletions elks/include/linuxmt/config.h
Expand Up @@ -28,7 +28,7 @@
#define SETUP_CPU_TYPE setupb(0x20) /* processor type */
#define SETUP_MEM_KBYTES setupw(0x2a) /* base memory in 1K bytes */
#define SETUP_ROOT_DEV setupw(0x1fc) /* root device, kdev_t or BIOS dev */
#define SETUP_ELKS_FLAGS setupw(0x1f6) /* flags for root device type */
#define SETUP_ELKS_FLAGS setupb(0x1f6) /* flags for root device type */
#define SETUP_PART_OFFSETLO setupw(0x1e2) /* partition offset low word */
#define SETUP_PART_OFFSETHI setupw(0x1e4) /* partition offset high word */
#ifdef CONFIG_ROMCODE
Expand All @@ -43,7 +43,7 @@
#define SETUP_CPU_TYPE 1 /* processor type = 8086 */
#define SETUP_MEM_KBYTES 640 /* base memory in 1K bytes */
#define SETUP_ROOT_DEV setupw(0x1fc) /* root device, kdev_t or BIOS dev */
#define SETUP_ELKS_FLAGS setupw(0x1f6) /* flags for root device type */
#define SETUP_ELKS_FLAGS setupb(0x1f6) /* flags for root device type */
#define SETUP_PART_OFFSETLO setupw(0x1e2) /* partition offset low word */
#define SETUP_PART_OFFSETHI setupw(0x1e4) /* partition offset high word */
#define SYS_CAPS 0 /* no XT/AT capabilities */
Expand Down

0 comments on commit 99b4a05

Please sign in to comment.