iso9660: back to stage2+decompressor
This commit is contained in:
parent
1a5cb00cda
commit
7677c6109d
2
Makefile
2
Makefile
@ -119,5 +119,5 @@ iso9660-test: | test-clean test.hdd bootloader all
|
|||||||
rm -rf test_image/
|
rm -rf test_image/
|
||||||
mkdir -p test_image/boot
|
mkdir -p test_image/boot
|
||||||
cp -rv bin/* test/* 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
|
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -cdrom test.iso -debugcon stdio
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
BITS 16
|
BITS 16
|
||||||
ORG 0x7C00
|
ORG 0x7C00
|
||||||
|
|
||||||
; Please read bootsect/bootsect.asm before this file
|
%define STAGE2_LOCATION 0x60000
|
||||||
|
%define DECOMPRESSOR_LOCATION 0x70000
|
||||||
%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 BOOT_FROM_CD 2
|
%define BOOT_FROM_CD 2
|
||||||
|
|
||||||
jmp skip_bpb
|
jmp skip_bpb
|
||||||
nop
|
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:
|
skip_bpb:
|
||||||
cli
|
cli
|
||||||
@ -41,31 +42,24 @@ skip_bpb:
|
|||||||
|
|
||||||
mov esp, 0x7C00
|
mov esp, 0x7C00
|
||||||
|
|
||||||
; --- Load the stage 2 ---
|
; --- Load the decompressor ---
|
||||||
; Find and load the PVD
|
mov eax, dword [bi_boot_LBA]
|
||||||
call findPVD
|
add eax, DEC_LBA_OFFSET
|
||||||
jc err
|
mov ecx, DEC_LBA_COUNT
|
||||||
|
; DECOMPRESSOR_LOCATION = 0x70000 = 0x7000:0x0000
|
||||||
; Load the root directory
|
mov si, 0x7000
|
||||||
mov eax, dword [ROOT_DIRECTORY_BUFFER + DIRECTORY_RECORD_LBA]
|
xor di, di
|
||||||
mov ecx, dword [ROOT_DIRECTORY_BUFFER + DIRECTORY_RECORD_SIZE]
|
|
||||||
|
|
||||||
mov esi, ecx ; Size, for read_file
|
|
||||||
add ecx, 2047
|
|
||||||
shr ecx, 11
|
|
||||||
call read_2k_sectors
|
call read_2k_sectors
|
||||||
jc err
|
jc err
|
||||||
|
|
||||||
; Find and load '/BOOT'
|
; --- Load the stage2.bin.gz ---
|
||||||
mov ebx, TXT_BOOT
|
mov eax, dword [bi_boot_LBA]
|
||||||
mov cl, TXT_BOOT_SZ
|
add eax, STAGE2_LBA_OFFSET
|
||||||
call read_file
|
mov ecx, STAGE2_LBA_COUNT
|
||||||
jc err
|
; STAGE2_LOCATION = 0x60000 = 0x6000:0x0000
|
||||||
|
mov si, 0x6000
|
||||||
; Find and load '/BOOT/LIMINE.SYS'
|
xor di, di
|
||||||
mov ebx, TXT_LIMINE
|
call read_2k_sectors
|
||||||
mov cl, TXT_LIMINE_SZ
|
|
||||||
call read_file ; esi is set from the last call
|
|
||||||
jc err
|
jc err
|
||||||
|
|
||||||
; Enable GDT
|
; Enable GDT
|
||||||
@ -81,7 +75,7 @@ err:
|
|||||||
hlt
|
hlt
|
||||||
jmp err
|
jmp err
|
||||||
|
|
||||||
%include 'iso9660.asm'
|
%include 'read_2k_sectors.asm'
|
||||||
%include '../gdt.asm'
|
%include '../gdt.asm'
|
||||||
|
|
||||||
BITS 32
|
BITS 32
|
||||||
@ -93,17 +87,28 @@ pmode:
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, 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
|
push BOOT_FROM_CD
|
||||||
and edx, 0xFF
|
and edx, 0xFF
|
||||||
push edx ; Boot drive
|
push edx ; Boot drive
|
||||||
call ISO9660_BUFFER
|
push STAGE2_SIZE
|
||||||
|
push STAGE2_LOCATION
|
||||||
|
call DECOMPRESSOR_LOCATION
|
||||||
hlt
|
hlt
|
||||||
|
|
||||||
TXT_BOOT: db "BOOT"
|
%define FILEPOS ($-$$)
|
||||||
TXT_BOOT_SZ equ $ - TXT_BOOT
|
%define UPPER2K ((FILEPOS+2047) & ~2047)
|
||||||
TXT_LIMINE: db "LIMINE.SYS;1"
|
%define ALIGN2K times UPPER2K - FILEPOS db 0
|
||||||
TXT_LIMINE_SZ equ $ - TXT_LIMINE
|
|
||||||
|
|
||||||
; Just making sure the entry point (ISO9660_BUFFER) is not reached
|
; Align stage2 to 2K ON DISK
|
||||||
times (0x8000 - 0x7C00) - ($ - $$) db 0
|
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
|
||||||
|
@ -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'
|
|
@ -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
|
|
@ -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
|
|
@ -6,6 +6,8 @@ BITS 16
|
|||||||
; cx <- number of 2k sectors
|
; cx <- number of 2k sectors
|
||||||
; dl <- drive number
|
; dl <- drive number
|
||||||
; ds <- ZERO
|
; ds <- ZERO
|
||||||
|
; di <- buffer offset
|
||||||
|
; si <- buffer segment
|
||||||
|
|
||||||
; OUT:
|
; OUT:
|
||||||
; Carry if error
|
; Carry if error
|
||||||
@ -15,13 +17,16 @@ dapack:
|
|||||||
dapack_size: db 0x10
|
dapack_size: db 0x10
|
||||||
dapack_null: db 0x00
|
dapack_null: db 0x00
|
||||||
dapack_nblocks: dw 0
|
dapack_nblocks: dw 0
|
||||||
dapack_buffer: dd ISO9660_BUFFER
|
dapack_offset: dw 0
|
||||||
|
dapack_segment: dw 0
|
||||||
dapack_LBA: dq 0
|
dapack_LBA: dq 0
|
||||||
|
|
||||||
read_2k_sectors:
|
read_2k_sectors:
|
||||||
pusha
|
pusha
|
||||||
mov dword [dapack_LBA], eax
|
mov dword [dapack_LBA], eax
|
||||||
mov word [dapack_nblocks], cx
|
mov word [dapack_nblocks], cx
|
||||||
|
mov word [dapack_offset], di
|
||||||
|
mov word [dapack_segment], si
|
||||||
|
|
||||||
mov ah, 0x42
|
mov ah, 0x42
|
||||||
mov si, dapack
|
mov si, dapack
|
||||||
|
@ -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
|
|
@ -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) {
|
int fopen(struct file_handle *ret, struct volume *part, const char *filename) {
|
||||||
ret->is_memfile = false;
|
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));
|
struct iso9660_file_handle *fd = ext_mem_alloc(sizeof(struct iso9660_file_handle));
|
||||||
|
|
||||||
int r = iso9660_open(fd, part, filename);
|
int r = iso9660_open(fd, part, filename);
|
||||||
|
@ -72,9 +72,9 @@ struct iso9660_contexts_node {
|
|||||||
struct iso9660_context context;
|
struct iso9660_context context;
|
||||||
struct iso9660_contexts_node *next;
|
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;
|
uint32_t lba = ISO9660_FIRST_VOLUME_DESCRIPTOR;
|
||||||
while (true) {
|
while (true) {
|
||||||
volume_read(vol, desc, lba * ISO9660_SECTOR_SIZE, ISO9660_SECTOR_SIZE);
|
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,
|
void **root,
|
||||||
uint32_t *root_size) {
|
uint32_t *root_size) {
|
||||||
struct iso9660_primary_volume pv;
|
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);
|
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;
|
struct iso9660_contexts_node *current = contexts;
|
||||||
while (current) {
|
while (current) {
|
||||||
if (current->context.vol.drive == vol->drive)
|
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;
|
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--) {
|
while (size--) {
|
||||||
char ca = *a++;
|
char ca = *a++;
|
||||||
char cb = *b++;
|
char cb = *b++;
|
||||||
@ -131,7 +131,7 @@ stage3_text static int iso9660_strcmp(const char *a, const char *b, size_t size)
|
|||||||
return 0;
|
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
|
// The file can be either FILENAME or FILENAME;1
|
||||||
uint32_t len = strlen(filename);
|
uint32_t len = strlen(filename);
|
||||||
char finalfile[len + 2];
|
char finalfile[len + 2];
|
||||||
@ -160,7 +160,7 @@ stage3_text static struct iso9660_directory_entry *iso9660_find(void *buffer, ui
|
|||||||
|
|
||||||
|
|
||||||
// --- Public functions ---
|
// --- Public functions ---
|
||||||
stage3_text int iso9660_check_signature(struct volume *vol) {
|
int iso9660_check_signature(struct volume *vol) {
|
||||||
char buf[6];
|
char buf[6];
|
||||||
const uint64_t signature = ISO9660_FIRST_VOLUME_DESCRIPTOR * ISO9660_SECTOR_SIZE + 1;
|
const uint64_t signature = ISO9660_FIRST_VOLUME_DESCRIPTOR * ISO9660_SECTOR_SIZE + 1;
|
||||||
volume_read(vol, buf, signature, 5);
|
volume_read(vol, buf, signature, 5);
|
||||||
@ -168,7 +168,7 @@ stage3_text int iso9660_check_signature(struct volume *vol) {
|
|||||||
return !strcmp(buf, "CD001");
|
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);
|
ret->context = iso9660_get_context(vol);
|
||||||
|
|
||||||
while (*path == '/')
|
while (*path == '/')
|
||||||
@ -207,7 +207,7 @@ stage3_text int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol
|
|||||||
return 0;
|
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);
|
volume_read(&file->context->vol, buf, file->LBA * ISO9660_SECTOR_SIZE + loc, count);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ void entry(uint8_t _boot_drive, int boot_from) {
|
|||||||
|
|
||||||
booted_from_pxe = (boot_from == BOOT_FROM_PXE);
|
booted_from_pxe = (boot_from == BOOT_FROM_PXE);
|
||||||
booted_from_cd = (boot_from == BOOT_FROM_CD);
|
booted_from_cd = (boot_from == BOOT_FROM_CD);
|
||||||
stage3_loaded = booted_from_cd; // CD loads both stages
|
|
||||||
|
|
||||||
mtrr_save();
|
mtrr_save();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user