:: commit 7677c6109da784c4cd891178df673aed1be6a285

JlXip <jlxip@protonmail.com> — 2021-02-25 00:40

parents: 1a5cb00cda

iso9660: back to stage2+decompressor

diff --git a/Makefile b/Makefile
index 72c83ef1..eccd6b39 100644
--- a/Makefile
+++ b/Makefile
@@ -119,5 +119,5 @@ iso9660-test: | test-clean test.hdd bootloader all
 	rm -rf test_image/
 	mkdir -p test_image/boot
 	cp -rv bin/* test/* test_image/boot/
-	genisoimage -no-emul-boot -b boot/limine-cd.bin -o test.iso test_image/
+	genisoimage -no-emul-boot -b boot/limine-cd.bin -boot-load-size 4 -boot-info-table -o test.iso test_image/
 	qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -cdrom test.iso -debugcon stdio
diff --git a/stage1/cd/bootsect.asm b/stage1/cd/bootsect.asm
index 69d346fc..2965adb5 100644
--- a/stage1/cd/bootsect.asm
+++ b/stage1/cd/bootsect.asm
@@ -1,23 +1,24 @@
 BITS 16
 ORG 0x7C00
 
-; Please read bootsect/bootsect.asm before this file
-
-%define ISO9660_BUFFER 0x8000
-%define ROOT_DIRECTORY 156
-%define ROOT_DIRECTORY_BUFFER (ISO9660_BUFFER + ROOT_DIRECTORY)
-
-%define DIRECTORY_RECORD_LENGTH 0
-%define DIRECTORY_RECORD_LBA 2
-%define DIRECTORY_RECORD_SIZE 10
-%define DIRECTORY_RECORD_FILENAME_LENGTH 32
-%define DIRECTORY_RECORD_FILENAME 33
-
+%define STAGE2_LOCATION       0x60000
+%define DECOMPRESSOR_LOCATION 0x70000
 %define BOOT_FROM_CD 2
 
 jmp skip_bpb
 nop
-times 87 db 0
+
+; El Torito Boot Information Table
+; ↓ Set by mkisofs
+times 8-($-$$) db 0
+boot_info:
+    bi_PVD      dd 0
+    bi_boot_LBA dd 0
+    bi_boot_len dd 0
+    bi_checksum dd 0
+    bi_reserved times 40 db 0
+
+times 90-($-$$) db 0
 
 skip_bpb:
     cli
@@ -41,31 +42,24 @@ skip_bpb:
 
     mov esp, 0x7C00
 
-    ; --- Load the stage 2 ---
-    ; Find and load the PVD
-    call findPVD
-    jc err
-
-    ; Load the root directory
-    mov eax, dword [ROOT_DIRECTORY_BUFFER + DIRECTORY_RECORD_LBA]
-    mov ecx, dword [ROOT_DIRECTORY_BUFFER + DIRECTORY_RECORD_SIZE]
-
-    mov esi, ecx  ; Size, for read_file
-    add ecx, 2047
-    shr ecx, 11
+    ; --- Load the decompressor ---
+    mov eax, dword [bi_boot_LBA]
+    add eax, DEC_LBA_OFFSET
+    mov ecx, DEC_LBA_COUNT
+    ; DECOMPRESSOR_LOCATION = 0x70000 = 0x7000:0x0000
+    mov si, 0x7000
+    xor di, di
     call read_2k_sectors
     jc err
 
-    ; Find and load '/BOOT'
-    mov ebx, TXT_BOOT
-    mov cl, TXT_BOOT_SZ
-    call read_file
-    jc err
-
-    ; Find and load '/BOOT/LIMINE.SYS'
-    mov ebx, TXT_LIMINE
-    mov cl, TXT_LIMINE_SZ
-    call read_file  ; esi is set from the last call
+    ; --- Load the stage2.bin.gz ---
+    mov eax, dword [bi_boot_LBA]
+    add eax, STAGE2_LBA_OFFSET
+    mov ecx, STAGE2_LBA_COUNT
+    ; STAGE2_LOCATION = 0x60000 = 0x6000:0x0000
+    mov si, 0x6000
+    xor di, di
+    call read_2k_sectors
     jc err
 
     ; Enable GDT
@@ -81,7 +75,7 @@ err:
     hlt
     jmp err
 
-%include 'iso9660.asm'
+%include 'read_2k_sectors.asm'
 %include '../gdt.asm'
 
 BITS 32
@@ -93,17 +87,28 @@ pmode:
     mov gs, ax
     mov ss, ax
 
-    ; Time to handle control over to the stage 2
+    ; Time to handle control over to the decompressor
     push BOOT_FROM_CD
     and edx, 0xFF
     push edx  ; Boot drive
-    call ISO9660_BUFFER
+    push STAGE2_SIZE
+    push STAGE2_LOCATION
+    call DECOMPRESSOR_LOCATION
     hlt
 
-TXT_BOOT: db "BOOT"
-TXT_BOOT_SZ equ $ - TXT_BOOT
-TXT_LIMINE: db "LIMINE.SYS;1"
-TXT_LIMINE_SZ equ $ - TXT_LIMINE
-
-; Just making sure the entry point (ISO9660_BUFFER) is not reached
-times (0x8000 - 0x7C00) - ($ - $$) db 0
+%define FILEPOS ($-$$)
+%define UPPER2K ((FILEPOS+2047) & ~2047)
+%define ALIGN2K times UPPER2K - FILEPOS db 0
+
+; Align stage2 to 2K ON DISK
+ALIGN2K
+DEC_LBA_OFFSET equ ($-$$)/2048
+incbin '../../decompressor/decompressor.bin'
+
+ALIGN2K
+STAGE2_START equ $-$$
+STAGE2_LBA_OFFSET equ STAGE2_START/2048
+DEC_LBA_COUNT equ STAGE2_LBA_OFFSET - DEC_LBA_OFFSET
+incbin '../../stage23/stage2.bin.gz'
+STAGE2_SIZE equ ($-$$) - STAGE2_START
+STAGE2_LBA_COUNT equ (2047 + $-$$)/2048
diff --git a/stage1/cd/findFile.asm b/stage1/cd/findFile.asm
deleted file mode 100644
index 0a66a2d1..00000000
--- a/stage1/cd/findFile.asm
+++ /dev/null
@@ -1,58 +0,0 @@
-BITS 16
-
-; --- Find file in directory ---
-; IN:
-; eax <- directory extent
-; ebx <- ptr to filename
-; cl  <- filename sz
-; esi <- size of directory extent
-
-; OUT:
-; eax <- LBA of the extent
-; ebx <- size in bytes
-; Carry if not found
-
-; SMASHES:
-; ch
-findFile:
-    push edx
-    push edi
-    push esi
-    mov edx, eax
-
-  .checkEntry:
-    ; Get the size of this entry
-    mov edi, dword [edx + DIRECTORY_RECORD_LENGTH]
-    and edi, 0xFF
-
-    ; Check filename size
-    mov al, byte [edx + DIRECTORY_RECORD_FILENAME_LENGTH]
-    cmp al, cl
-    jnz .gonext
-
-    ; Sizes match, check filename
-    lea eax, dword [edx + DIRECTORY_RECORD_FILENAME]
-    call strcmp
-    jnc .found
-
-    ; Go to the next
-  .gonext:
-    add edx, edi
-    sub esi, edi
-    test esi, esi
-    jnz .checkEntry
-
-  .notfound:
-    stc
-    jmp .end
-  .found:
-    clc
-    mov eax, [edx + DIRECTORY_RECORD_LBA]
-    mov ebx, [edx + DIRECTORY_RECORD_SIZE]
-  .end:
-    pop esi
-    pop edi
-    pop edx
-    ret
-
-%include 'strcmp.asm'
diff --git a/stage1/cd/findPVD.asm b/stage1/cd/findPVD.asm
deleted file mode 100644
index 6f9b94d2..00000000
--- a/stage1/cd/findPVD.asm
+++ /dev/null
@@ -1,51 +0,0 @@
-BITS 16
-
-; --- Find primary volume descriptor ---
-; IN:
-; dl <- drive number
-
-; OUT:
-; [ISO9660_BUFFER] <- PVD
-; Carry if not found
-findPVD:
-    pusha
-    ; Just start reading volume descriptors
-
-    mov eax, 0x10    ; First volume descriptor's LBA
-  .checkVD:
-    mov cx, 1    ; Each volume descriptor is 2KB
-    call read_2k_sectors
-
-    ; Check identifier
-    mov ecx, ISO9660_BUFFER
-    inc ecx
-    mov bl, byte [ecx]
-    inc ecx
-    mov ecx, dword [ecx]
-    cmp bl, 'C'
-    jne .notfound
-    cmp ecx, 0x31303044
-    jne .notfound
-
-    ; Check type = 0xFF (final)
-    mov ecx, ISO9660_BUFFER
-    mov bl, byte [ecx]
-    cmp bl, 0xFF
-    jz .notfound
-
-    ; Check type = 0x01 (PVD)
-    cmp bl, 0x01
-    jz .found
-
-    ; Didn't match, go to the next
-    inc eax
-    jmp .checkVD
-
-  .found:
-    clc
-    jmp .end
-  .notfound:
-    stc
-  .end:
-    popa
-    ret
diff --git a/stage1/cd/iso9660.asm b/stage1/cd/iso9660.asm
deleted file mode 100644
index 28f1551f..00000000
--- a/stage1/cd/iso9660.asm
+++ /dev/null
@@ -1,35 +0,0 @@
-BITS 16
-
-%include 'read_2k_sectors.asm'
-%include 'findPVD.asm'
-%include 'findFile.asm'
-
-; --- Read file ---
-; IN:
-; ebx <- ptr to filename
-; cl <- filename sz
-; esi <- size of directory extent
-
-; OUT:
-; If found: [ISO9660_BUFFER] <- contents of the file
-; If not found: CF=1
-; esi <- size in bytes
-
-; SMASHES:
-; eax, ebx, ecx
-read_file:
-    mov eax, ISO9660_BUFFER
-    call findFile
-    jc .end
-
-    ; LBA of the extent is now @ eax
-    ; ebx is size in bytes
-    mov esi, ebx  ; Return value
-
-    ; bytes to 2k sectors
-    mov ecx, ebx
-    add ecx, 2047
-    shr ecx, 11
-    call read_2k_sectors
-  .end:
-    ret
diff --git a/stage1/cd/read_2k_sectors.asm b/stage1/cd/read_2k_sectors.asm
index f5d3dd16..7ebd0ba5 100644
--- a/stage1/cd/read_2k_sectors.asm
+++ b/stage1/cd/read_2k_sectors.asm
@@ -6,6 +6,8 @@ BITS 16
 ; cx <- number of 2k sectors
 ; dl <- drive number
 ; ds <- ZERO
+; di <- buffer offset
+; si <- buffer segment
 
 ; OUT:
 ; Carry if error
@@ -15,13 +17,16 @@ dapack:
     dapack_size:    db 0x10
     dapack_null:    db 0x00
     dapack_nblocks: dw 0
-    dapack_buffer:  dd ISO9660_BUFFER
+    dapack_offset:  dw 0
+    dapack_segment: dw 0
     dapack_LBA:     dq 0
 
 read_2k_sectors:
     pusha
     mov dword [dapack_LBA], eax
     mov word  [dapack_nblocks], cx
+    mov word  [dapack_offset], di
+    mov word  [dapack_segment], si
 
     mov ah, 0x42
     mov si, dapack
diff --git a/stage1/cd/strcmp.asm b/stage1/cd/strcmp.asm
deleted file mode 100644
index fd21186f..00000000
--- a/stage1/cd/strcmp.asm
+++ /dev/null
@@ -1,34 +0,0 @@
-BITS 16
-
-; --- Compare strings ---
-; IN:
-; eax <- ptr to first string
-; ebx <- ptr to second string
-; cl <- size of BOTH strings (must be the same)
-
-; OUT:
-; CF=0 if equal, CF=1 otherwise
-strcmp:
-    pusha
-  .nextchar:
-    mov dh, byte [eax]
-    mov dl, byte [ebx]
-    cmp dh, dl
-    jnz .notequal
-
-    ; Characters match
-    dec cl
-    test cl, cl
-    jz .equal
-    inc eax
-    inc ebx
-    jmp .nextchar
-
-  .equal:
-    clc
-    jmp .end
-  .notequal:
-    stc
-  .end:
-    popa
-    ret
diff --git a/stage23/fs/file.c b/stage23/fs/file.c
index 016532cd..8fbc65c4 100644
--- a/stage23/fs/file.c
+++ b/stage23/fs/file.c
@@ -24,7 +24,7 @@ bool fs_get_guid(struct guid *guid, struct volume *part) {
 int fopen(struct file_handle *ret, struct volume *part, const char *filename) {
     ret->is_memfile = false;
 
-    if (stage3_loaded && iso9660_check_signature(part)) {
+    if (iso9660_check_signature(part)) {
         struct iso9660_file_handle *fd = ext_mem_alloc(sizeof(struct iso9660_file_handle));
 
         int r = iso9660_open(fd, part, filename);
diff --git a/stage23/fs/iso9660.c b/stage23/fs/iso9660.c
index 978ef1c8..4bfc9198 100644
--- a/stage23/fs/iso9660.c
+++ b/stage23/fs/iso9660.c
@@ -72,9 +72,9 @@ struct iso9660_contexts_node {
     struct iso9660_context context;
     struct iso9660_contexts_node *next;
 };
-stage3_data struct iso9660_contexts_node *contexts = NULL;
+struct iso9660_contexts_node *contexts = NULL;
 
-stage3_text static void iso9660_find_PVD(struct iso9660_volume_descriptor *desc, struct volume *vol) {
+static void iso9660_find_PVD(struct iso9660_volume_descriptor *desc, struct volume *vol) {
     uint32_t lba = ISO9660_FIRST_VOLUME_DESCRIPTOR;
     while (true) {
         volume_read(vol, desc, lba * ISO9660_SECTOR_SIZE, ISO9660_SECTOR_SIZE);
@@ -91,7 +91,7 @@ stage3_text static void iso9660_find_PVD(struct iso9660_volume_descriptor *desc,
     }
 }
 
-stage3_text static void iso9660_cache_root(struct volume *vol,
+static void iso9660_cache_root(struct volume *vol,
                                void **root,
                                uint32_t *root_size) {
     struct iso9660_primary_volume pv;
@@ -102,7 +102,7 @@ stage3_text static void iso9660_cache_root(struct volume *vol,
     volume_read(vol, *root, pv.root.extent.little * ISO9660_SECTOR_SIZE, *root_size);
 }
 
-stage3_text static struct iso9660_context *iso9660_get_context(struct volume *vol) {
+static struct iso9660_context *iso9660_get_context(struct volume *vol) {
     struct iso9660_contexts_node *current = contexts;
     while (current) {
         if (current->context.vol.drive == vol->drive)
@@ -120,7 +120,7 @@ stage3_text static struct iso9660_context *iso9660_get_context(struct volume *vo
     return &node->context;
 }
 
-stage3_text static int iso9660_strcmp(const char *a, const char *b, size_t size) {
+static int iso9660_strcmp(const char *a, const char *b, size_t size) {
     while (size--) {
         char ca = *a++;
         char cb = *b++;
@@ -131,7 +131,7 @@ stage3_text static int iso9660_strcmp(const char *a, const char *b, size_t size)
     return 0;
 }
 
-stage3_text static struct iso9660_directory_entry *iso9660_find(void *buffer, uint32_t size, const char *filename) {
+static struct iso9660_directory_entry *iso9660_find(void *buffer, uint32_t size, const char *filename) {
     // The file can be either FILENAME or FILENAME;1
     uint32_t len = strlen(filename);
     char finalfile[len + 2];
@@ -160,7 +160,7 @@ stage3_text static struct iso9660_directory_entry *iso9660_find(void *buffer, ui
 
 
 // --- Public functions ---
-stage3_text int iso9660_check_signature(struct volume *vol) {
+int iso9660_check_signature(struct volume *vol) {
     char buf[6];
     const uint64_t signature = ISO9660_FIRST_VOLUME_DESCRIPTOR * ISO9660_SECTOR_SIZE + 1;
     volume_read(vol, buf, signature, 5);
@@ -168,7 +168,7 @@ stage3_text int iso9660_check_signature(struct volume *vol) {
     return !strcmp(buf, "CD001");
 }
 
-stage3_text int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path) {
+int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path) {
     ret->context = iso9660_get_context(vol);
 
     while (*path == '/')
@@ -207,7 +207,7 @@ stage3_text int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol
     return 0;
 }
 
-stage3_text int iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count) {
+int iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count) {
     volume_read(&file->context->vol, buf, file->LBA * ISO9660_SECTOR_SIZE + loc, count);
     return 0;
 }
diff --git a/stage23/main.c b/stage23/main.c
index 76e7cc84..3086488c 100644
--- a/stage23/main.c
+++ b/stage23/main.c
@@ -31,7 +31,6 @@ void entry(uint8_t _boot_drive, int boot_from) {
 
     booted_from_pxe = (boot_from == BOOT_FROM_PXE);
     booted_from_cd = (boot_from == BOOT_FROM_CD);
-    stage3_loaded = booted_from_cd; // CD loads both stages
 
     mtrr_save();
 
tab: 248 wrap: offon