commit
60a3fab256
3
.gitignore
vendored
3
.gitignore
vendored
@ -7,11 +7,14 @@
|
||||
/**/*.bin.gz
|
||||
/**/*.elf
|
||||
/**/*.hdd
|
||||
/**/*.iso
|
||||
/bochsout.txt
|
||||
/bx_enh_dbg.ini
|
||||
.vscode
|
||||
/limine-install
|
||||
!/limine.bin
|
||||
!/limine-pxe.bin
|
||||
!/limine-cd.bin
|
||||
!/stage2.map
|
||||
/stivale
|
||||
/test_image
|
||||
|
18
Makefile
18
Makefile
@ -29,6 +29,7 @@ install: all
|
||||
bootloader: | decompressor stage2
|
||||
gzip -n -9 < stage2/stage2.bin > stage2/stage2.bin.gz
|
||||
cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin
|
||||
cd cdboot && nasm bootsect.asm -fbin -o ../limine-cd.bin
|
||||
cd pxeboot && nasm bootsect.asm -fbin -o ../limine-pxe.bin
|
||||
cp stage2/stage2.map ./
|
||||
cp stage2/stage3.bin ./limine.sys
|
||||
@ -93,12 +94,12 @@ ext2-test: test.hdd bootloader | all
|
||||
sudo mkfs.ext2 `cat loopback_dev`p1
|
||||
sudo mount `cat loopback_dev`p1 test_image
|
||||
sudo mkdir test_image/boot
|
||||
sudo cp -rv test/* test_image/boot/
|
||||
sudo cp -rv ./limine.sys test/* test_image/boot/
|
||||
sync
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
./limine-install test.hdd
|
||||
./limine-install ./ test.hdd
|
||||
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio
|
||||
|
||||
fat32-test: test.hdd bootloader | all
|
||||
@ -111,10 +112,19 @@ fat32-test: test.hdd bootloader | all
|
||||
sudo mkfs.fat -F 32 `cat loopback_dev`p1
|
||||
sudo mount `cat loopback_dev`p1 test_image
|
||||
sudo mkdir test_image/boot
|
||||
sudo cp -rv test/* test_image/boot/
|
||||
sudo cp -rv ./limine.sys test/* test_image/boot/
|
||||
sync
|
||||
sudo umount test_image/
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
./limine-install test.hdd
|
||||
./limine-install ./ test.hdd
|
||||
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio
|
||||
|
||||
iso9660-test: bootloader
|
||||
$(MAKE) -C test
|
||||
cp stage2.map test/
|
||||
rm -rf test_image/
|
||||
mkdir -p test_image/boot
|
||||
cp -rv limine-cd.bin limine.sys stage2/stages.bin test/* test_image/boot/
|
||||
genisoimage -no-emul-boot -b boot/limine-cd.bin -o test.iso test_image/
|
||||
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -cdrom test.iso -debugcon stdio
|
||||
|
109
cdboot/bootsect.asm
Normal file
109
cdboot/bootsect.asm
Normal file
@ -0,0 +1,109 @@
|
||||
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 BOOT_FROM_CD 2
|
||||
|
||||
jmp skip_bpb
|
||||
nop
|
||||
times 87 db 0
|
||||
|
||||
skip_bpb:
|
||||
cli
|
||||
cld
|
||||
jmp 0x0000:.initialise_cs
|
||||
.initialise_cs:
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov ss, ax
|
||||
mov sp, 0x7C00
|
||||
sti
|
||||
|
||||
; int 13h?
|
||||
mov ah, 0x41
|
||||
mov bx, 0x55AA
|
||||
int 0x13
|
||||
jc err
|
||||
cmp bx, 0xAA55
|
||||
jne err
|
||||
|
||||
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
|
||||
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/STAGES.BIN'
|
||||
mov ebx, TXT_STAGES
|
||||
mov cl, TXT_STAGES_SZ
|
||||
call read_file ; esi is set from the last call
|
||||
jc err
|
||||
|
||||
; Enable GDT
|
||||
lgdt [gdt]
|
||||
cli
|
||||
mov eax, cr0
|
||||
or al, 1
|
||||
mov cr0, eax
|
||||
|
||||
jmp 0x08:pmode
|
||||
|
||||
err:
|
||||
hlt
|
||||
jmp err
|
||||
|
||||
%include 'iso9660.asm'
|
||||
%include '../bootsect/gdt.inc'
|
||||
|
||||
BITS 32
|
||||
pmode:
|
||||
mov eax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
; Time to handle control over to the stage 2
|
||||
push BOOT_FROM_CD
|
||||
and edx, 0xFF
|
||||
push edx ; Boot drive
|
||||
call ISO9660_BUFFER
|
||||
hlt
|
||||
|
||||
TXT_BOOT: db "BOOT"
|
||||
TXT_BOOT_SZ equ $ - TXT_BOOT
|
||||
TXT_STAGES: db "STAGES.BIN;1"
|
||||
TXT_STAGES_SZ equ $ - TXT_STAGES
|
||||
|
||||
; Just making sure the entry point (ISO9660_BUFFER) is not reached
|
||||
times (0x8000 - 0x7C00) - ($ - $$) db 0
|
58
cdboot/findFile.asm
Normal file
58
cdboot/findFile.asm
Normal file
@ -0,0 +1,58 @@
|
||||
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'
|
51
cdboot/findPVD.asm
Normal file
51
cdboot/findPVD.asm
Normal file
@ -0,0 +1,51 @@
|
||||
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
|
35
cdboot/iso9660.asm
Normal file
35
cdboot/iso9660.asm
Normal file
@ -0,0 +1,35 @@
|
||||
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
|
30
cdboot/read_2k_sectors.asm
Normal file
30
cdboot/read_2k_sectors.asm
Normal file
@ -0,0 +1,30 @@
|
||||
BITS 16
|
||||
|
||||
; --- Read sectors from disk ---
|
||||
; IN:
|
||||
; eax <- start LBA (2k sectors)
|
||||
; cx <- number of 2k sectors
|
||||
; dl <- drive number
|
||||
; ds <- ZERO
|
||||
|
||||
; OUT:
|
||||
; Carry if error
|
||||
|
||||
align 8
|
||||
dapack:
|
||||
dapack_size: db 0x10
|
||||
dapack_null: db 0x00
|
||||
dapack_nblocks: dw 0
|
||||
dapack_buffer: dd ISO9660_BUFFER
|
||||
dapack_LBA: dq 0
|
||||
|
||||
read_2k_sectors:
|
||||
pusha
|
||||
mov dword [dapack_LBA], eax
|
||||
mov word [dapack_nblocks], cx
|
||||
|
||||
mov ah, 0x42
|
||||
mov si, dapack
|
||||
int 0x13
|
||||
popa
|
||||
ret
|
34
cdboot/strcmp.asm
Normal file
34
cdboot/strcmp.asm
Normal file
@ -0,0 +1,34 @@
|
||||
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
|
BIN
limine-cd.bin
Normal file
BIN
limine-cd.bin
Normal file
Binary file not shown.
BIN
limine-pxe.bin
BIN
limine-pxe.bin
Binary file not shown.
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
BIN
limine.sys
BIN
limine.sys
Binary file not shown.
@ -4,6 +4,7 @@
|
||||
#include <fs/echfs.h>
|
||||
#include <fs/ext2.h>
|
||||
#include <fs/fat32.h>
|
||||
#include <fs/iso9660.h>
|
||||
#include <lib/blib.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <lib/part.h>
|
||||
@ -23,6 +24,20 @@ 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 (iso9660_check_signature(part)) {
|
||||
struct iso9660_file_handle *fd = ext_mem_alloc(sizeof(struct iso9660_file_handle));
|
||||
|
||||
int r = iso9660_open(fd, part, filename);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ret->fd = (void *)fd;
|
||||
ret->read = (void *)iso9660_read;
|
||||
ret->size = fd->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (echfs_check_signature(part)) {
|
||||
struct echfs_file_handle *fd = ext_mem_alloc(sizeof(struct echfs_file_handle));
|
||||
|
||||
|
197
stage2/fs/iso9660.c
Normal file
197
stage2/fs/iso9660.c
Normal file
@ -0,0 +1,197 @@
|
||||
#include <fs/iso9660.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
#include <mm/pmm.h>
|
||||
|
||||
#define ISO9660_FIRST_VOLUME_DESCRIPTOR 0x10
|
||||
#define ISO9660_VOLUME_DESCRIPTOR_SIZE ISO9660_SECTOR_SIZE
|
||||
#define ROCK_RIDGE_MAX_FILENAME 255
|
||||
|
||||
// --- Both endian structures ---
|
||||
struct BE16_t { uint16_t little, big; } __attribute__((packed));
|
||||
struct BE32_t { uint32_t little, big; } __attribute__((packed));
|
||||
|
||||
// --- Directory entries ---
|
||||
struct iso9660_directory_entry {
|
||||
uint8_t length;
|
||||
uint8_t extended_attribute_length;
|
||||
struct BE32_t extent;
|
||||
struct BE32_t extent_size;
|
||||
uint8_t datetime[7];
|
||||
uint8_t flags;
|
||||
uint8_t interleaved_unit_size;
|
||||
uint8_t interleaved_gap_size;
|
||||
struct BE16_t volume_seq;
|
||||
uint8_t filename_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
// --- Volume descriptors ---
|
||||
// VDT = Volume Descriptor Type
|
||||
enum {
|
||||
ISO9660_VDT_BOOT_RECORD,
|
||||
ISO9660_VDT_PRIMARY,
|
||||
ISO9660_VDT_SUPPLEMENTARY,
|
||||
ISO9660_VDT_PARTITION_DESCRIPTOR,
|
||||
ISO9660_VDT_TERMINATOR = 255
|
||||
};
|
||||
|
||||
struct iso9660_volume_descriptor {
|
||||
uint8_t type;
|
||||
char identifier[5];
|
||||
uint8_t version;
|
||||
uint8_t data[2041];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct iso9660_primary_volume {
|
||||
uint8_t type;
|
||||
char standard_identifier[5];
|
||||
uint8_t version;
|
||||
uint8_t unused0[1];
|
||||
char system_identifier[32];
|
||||
char volume_identifier[32];
|
||||
uint8_t unused1[8];
|
||||
struct BE32_t space_size;
|
||||
uint8_t unused2[32];
|
||||
struct BE16_t set_size;
|
||||
struct BE16_t volume_seq;
|
||||
struct BE16_t LBA_size;
|
||||
struct BE32_t path_table_size;
|
||||
|
||||
uint32_t LBA_path_table_little;
|
||||
uint32_t LBA_optional_path_table_little;
|
||||
uint32_t LBA_path_table_big;
|
||||
uint32_t LBA_optional_path_table_big;
|
||||
|
||||
struct iso9660_directory_entry root;
|
||||
uint8_t no_one_cares[1858];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
// --- Implementation ---
|
||||
// Cached root
|
||||
static void *root = NULL;
|
||||
static uint32_t root_size = 0;
|
||||
|
||||
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);
|
||||
|
||||
switch (desc->type) {
|
||||
case ISO9660_VDT_PRIMARY:
|
||||
return;
|
||||
case ISO9660_VDT_TERMINATOR:
|
||||
panic("ISO9660: no primary volume descriptor");
|
||||
break;
|
||||
}
|
||||
|
||||
++lba;
|
||||
}
|
||||
}
|
||||
|
||||
static void iso9660_cache_root(struct volume *vol) {
|
||||
struct iso9660_primary_volume pv;
|
||||
iso9660_find_PVD((struct iso9660_volume_descriptor *)&pv, vol);
|
||||
|
||||
root_size = pv.root.extent_size.little;
|
||||
root = ext_mem_alloc(root_size);
|
||||
volume_read(vol, root, pv.root.extent.little * ISO9660_SECTOR_SIZE, root_size);
|
||||
}
|
||||
|
||||
static int iso9660_strcmp(const char *a, const char *b, size_t size) {
|
||||
while (size--) {
|
||||
char ca = *a++;
|
||||
char cb = *b++;
|
||||
if (!(ca == cb || (ca - ('a'-'A')) == cb))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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];
|
||||
strcpy(finalfile, filename);
|
||||
finalfile[len + 0] = ';';
|
||||
finalfile[len + 1] = '1';
|
||||
|
||||
while (size) {
|
||||
struct iso9660_directory_entry *entry = buffer;
|
||||
char* entry_filename = (char*)entry + sizeof(struct iso9660_directory_entry);
|
||||
|
||||
if (!entry->length) {
|
||||
return NULL;
|
||||
} else if (entry->filename_size == len && !iso9660_strcmp(filename, entry_filename, len)) {
|
||||
return buffer;
|
||||
} else if (entry->filename_size == len+2 && !iso9660_strcmp(finalfile, entry_filename, len+2)) {
|
||||
return buffer;
|
||||
} else {
|
||||
size -= entry->length;
|
||||
buffer += entry->length;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// --- Public functions ---
|
||||
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);
|
||||
buf[5] = '\0';
|
||||
return !strcmp(buf, "CD001");
|
||||
}
|
||||
|
||||
int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path) {
|
||||
// Is the root directory cached?
|
||||
if (!root)
|
||||
iso9660_cache_root(vol);
|
||||
|
||||
ret->context.vol = *vol;
|
||||
ret->context.root = root;
|
||||
ret->context.root_size = root_size;
|
||||
|
||||
while (*path == '/')
|
||||
++path;
|
||||
|
||||
struct iso9660_directory_entry *current = root;
|
||||
uint32_t current_size = root_size;
|
||||
|
||||
uint32_t next_sector = 0;
|
||||
uint32_t next_size = 0;
|
||||
|
||||
char filename[ROCK_RIDGE_MAX_FILENAME];
|
||||
while (true) {
|
||||
char *aux = filename;
|
||||
while (!(*path == '/' || *path == '\0'))
|
||||
*aux++ = *path++;
|
||||
*aux = '\0';
|
||||
|
||||
struct iso9660_directory_entry *entry = iso9660_find(current, current_size, filename);
|
||||
if (!entry)
|
||||
return 1; // Not found :(
|
||||
|
||||
next_sector = entry->extent.little;
|
||||
next_size = entry->extent_size.little;
|
||||
|
||||
if (*path++ == '\0')
|
||||
break; // Found :)
|
||||
|
||||
current_size = next_size;
|
||||
current = ext_mem_alloc(current_size);
|
||||
volume_read(vol, current, next_sector * ISO9660_SECTOR_SIZE, current_size);
|
||||
}
|
||||
|
||||
ret->LBA = next_sector;
|
||||
ret->size = next_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
25
stage2/fs/iso9660.h
Normal file
25
stage2/fs/iso9660.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef __FS__ISO9660_H__
|
||||
#define __FS__ISO9660_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <lib/part.h>
|
||||
|
||||
#define ISO9660_SECTOR_SIZE (2 << 10)
|
||||
|
||||
struct iso9660_context {
|
||||
struct volume vol;
|
||||
void* root;
|
||||
uint32_t root_size;
|
||||
};
|
||||
|
||||
struct iso9660_file_handle {
|
||||
struct iso9660_context context;
|
||||
uint32_t LBA;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
int iso9660_check_signature(struct volume *vol);
|
||||
int iso9660_open(struct iso9660_file_handle *ret, struct volume *vol, const char *path);
|
||||
int iso9660_read(struct iso9660_file_handle *file, void *buf, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
@ -11,6 +11,8 @@ uint8_t boot_drive;
|
||||
int boot_partition = -1;
|
||||
|
||||
bool booted_from_pxe = false;
|
||||
bool booted_from_cd = false;
|
||||
bool stage3_already_loaded = false;
|
||||
|
||||
bool parse_resolution(int *width, int *height, int *bpp, const char *buf) {
|
||||
int res[3] = {0};
|
||||
|
@ -9,6 +9,8 @@ extern uint8_t boot_drive;
|
||||
extern int boot_partition;
|
||||
|
||||
extern bool booted_from_pxe;
|
||||
extern bool booted_from_cd;
|
||||
extern bool stage3_already_loaded;
|
||||
|
||||
bool parse_resolution(int *width, int *height, int *bpp, const char *buf);
|
||||
|
||||
|
@ -19,15 +19,17 @@ static char *config_addr;
|
||||
extern symbol stage3_addr;
|
||||
|
||||
int init_config_disk(struct volume *part) {
|
||||
struct file_handle stage3;
|
||||
if (!stage3_already_loaded) {
|
||||
struct file_handle stage3;
|
||||
|
||||
if (fopen(&stage3, part, "/limine.sys")
|
||||
&& fopen(&stage3, part, "/boot/limine.sys")) {
|
||||
panic("Could not open stage 3");
|
||||
if (fopen(&stage3, part, "/limine.sys")
|
||||
&& fopen(&stage3, part, "/boot/limine.sys")) {
|
||||
panic("Could not open stage 3");
|
||||
}
|
||||
|
||||
fread(&stage3, stage3_addr, 0, stage3.size);
|
||||
}
|
||||
|
||||
fread(&stage3, stage3_addr, 0, stage3.size);
|
||||
|
||||
struct file_handle f;
|
||||
|
||||
if (fopen(&f, part, "/limine.cfg")
|
||||
|
@ -254,7 +254,7 @@ static size_t volume_index_i = 0;
|
||||
void volume_create_index(void) {
|
||||
size_t volume_count = 0;
|
||||
|
||||
for (uint8_t drive = 0x80; drive < 0x8f; drive++) {
|
||||
for (uint8_t drive = 0x80; drive; drive++) {
|
||||
struct rm_regs r = {0};
|
||||
struct bios_drive_params drive_params;
|
||||
|
||||
@ -298,7 +298,7 @@ void volume_create_index(void) {
|
||||
|
||||
volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
|
||||
|
||||
for (uint8_t drive = 0x80; drive < 0x8f; drive++) {
|
||||
for (uint8_t drive = 0x80; drive; drive++) {
|
||||
struct rm_regs r = {0};
|
||||
struct bios_drive_params drive_params;
|
||||
|
||||
|
@ -94,10 +94,10 @@ static bool parse_bios_partition(char *loc, uint8_t *drive, uint8_t *partition)
|
||||
static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
|
||||
uint8_t drive, partition;
|
||||
|
||||
struct volume volume;
|
||||
if (!parse_bios_partition(loc, &drive, &partition))
|
||||
return false;
|
||||
|
||||
struct volume volume;
|
||||
if (!volume_get_by_coord(&volume, drive, partition))
|
||||
return false;
|
||||
|
||||
@ -154,7 +154,7 @@ static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path)
|
||||
if (booted_from_pxe)
|
||||
return uri_tftp_dispatch(fd, s_part, path);
|
||||
|
||||
uint8_t partition;
|
||||
int partition;
|
||||
|
||||
if (s_part[0] != '\0') {
|
||||
uint64_t val = strtoui(s_part, NULL, 10);
|
||||
@ -162,12 +162,10 @@ static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path)
|
||||
panic("Partition number outside range 1-256");
|
||||
}
|
||||
partition = val - 1;
|
||||
} else if (booted_from_cd || boot_partition != -1) {
|
||||
partition = boot_partition;
|
||||
} else {
|
||||
if (boot_partition != -1) {
|
||||
partition = boot_partition;
|
||||
} else {
|
||||
panic("Boot partition information is unavailable.");
|
||||
}
|
||||
panic("Boot partition information is unavailable.");
|
||||
}
|
||||
|
||||
struct volume part;
|
||||
|
@ -20,10 +20,18 @@
|
||||
#include <pxe/pxe.h>
|
||||
#include <pxe/tftp.h>
|
||||
|
||||
void entry(uint8_t _boot_drive, int pxe_boot) {
|
||||
enum {
|
||||
BOOT_FROM_HDD,
|
||||
BOOT_FROM_PXE,
|
||||
BOOT_FROM_CD
|
||||
};
|
||||
|
||||
void entry(uint8_t _boot_drive, int boot_from) {
|
||||
boot_drive = _boot_drive;
|
||||
|
||||
booted_from_pxe = pxe_boot;
|
||||
booted_from_pxe = (boot_from == BOOT_FROM_PXE);
|
||||
booted_from_cd = (boot_from == BOOT_FROM_CD);
|
||||
stage3_already_loaded = booted_from_cd; // CD loads both stages
|
||||
|
||||
mtrr_save();
|
||||
|
||||
@ -37,20 +45,15 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
|
||||
init_e820();
|
||||
init_memmap();
|
||||
|
||||
struct volume part;
|
||||
volume_create_index();
|
||||
|
||||
if (pxe_boot) {
|
||||
pxe_init();
|
||||
if (init_config_pxe()) {
|
||||
panic("Failed to load config file");
|
||||
}
|
||||
print("Config loaded via PXE\n");
|
||||
} else {
|
||||
switch (boot_from) {
|
||||
case BOOT_FROM_HDD:
|
||||
print("Boot drive: %x\n", boot_drive);
|
||||
// Look for config file.
|
||||
print("Searching for config file...\n");
|
||||
for (int i = 0; ; i++) {
|
||||
struct volume part;
|
||||
int ret = volume_get_by_coord(&part, boot_drive, i);
|
||||
switch (ret) {
|
||||
case INVALID_TABLE:
|
||||
@ -66,6 +69,22 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BOOT_FROM_PXE:
|
||||
pxe_init();
|
||||
if (init_config_pxe()) {
|
||||
panic("Failed to load config file");
|
||||
}
|
||||
print("Config loaded via PXE\n");
|
||||
break;
|
||||
|
||||
case BOOT_FROM_CD:
|
||||
boot_partition = -1; // raw device
|
||||
volume_get_by_coord(&part, boot_drive, boot_partition);
|
||||
if (init_config_disk(&part))
|
||||
panic("Failed to load config file");
|
||||
break;
|
||||
}
|
||||
|
||||
trace_init();
|
||||
@ -81,7 +100,7 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
|
||||
if (!strcmp(proto, "stivale")) {
|
||||
stivale_load(config, cmdline);
|
||||
} else if (!strcmp(proto, "stivale2")) {
|
||||
stivale2_load(config, cmdline, pxe_boot);
|
||||
stivale2_load(config, cmdline, boot_from);
|
||||
} else if (!strcmp(proto, "linux")) {
|
||||
linux_load(config, cmdline);
|
||||
} else if (!strcmp(proto, "chainload")) {
|
||||
|
@ -5,48 +5,48 @@ GRAPHICS=yes
|
||||
MENU_RESOLUTION=1024x768
|
||||
MENU_FONT=boot:///boot/font.bin
|
||||
E9_OUTPUT=yes
|
||||
STAGE2_MAP=bios://:1/boot/stage2.map
|
||||
STAGE2_MAP=boot:///boot/stage2.map
|
||||
|
||||
THEME_COLOURS=60000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa
|
||||
THEME_MARGIN=64
|
||||
|
||||
BACKGROUND_PATH=bios://:1/boot/bg.bmp
|
||||
BACKGROUND_PATH=boot:///boot/bg.bmp
|
||||
|
||||
:+Legacy
|
||||
|
||||
::Stivale Test
|
||||
|
||||
PROTOCOL=stivale
|
||||
KERNEL_PATH=boot://1/boot/test.elf
|
||||
KERNEL_PATH=boot:///boot/test.elf
|
||||
KERNEL_CMDLINE=Hi! This is an example!
|
||||
|
||||
MODULE_PATH=bios://:1/boot/test.elf
|
||||
MODULE_PATH=boot:///boot/test.elf
|
||||
MODULE_STRING=yooooo
|
||||
|
||||
MODULE_PATH=bios://:1/boot/bg.bmp
|
||||
MODULE_PATH=boot:///boot/bg.bmp
|
||||
MODULE_STRING=yooooo
|
||||
|
||||
::Stivale Test (KASLR)
|
||||
|
||||
PROTOCOL=stivale
|
||||
KASLR=yes
|
||||
KERNEL_PATH=boot://1/boot/test.elf
|
||||
KERNEL_PATH=boot:///boot/test.elf
|
||||
KERNEL_CMDLINE=Hi! This is an example!
|
||||
|
||||
MODULE_PATH=bios://:1/boot/test.elf
|
||||
MODULE_PATH=boot:///boot/test.elf
|
||||
MODULE_STRING=yooooo
|
||||
|
||||
MODULE_PATH=bios://:1/boot/bg.bmp
|
||||
MODULE_PATH=boot:///boot/bg.bmp
|
||||
MODULE_STRING=yooooo
|
||||
|
||||
:Stivale2 Test
|
||||
|
||||
PROTOCOL=stivale2
|
||||
RESOLUTION=640x480x16
|
||||
KERNEL_PATH=bios://:1/boot/test.elf
|
||||
KERNEL_PATH=boot:///boot/test.elf
|
||||
KERNEL_CMDLINE=Woah! Another example!
|
||||
|
||||
MODULE_PATH=bios://:1/boot/bg.bmp
|
||||
MODULE_PATH=boot:///boot/bg.bmp
|
||||
MODULE_STRING=yooooo
|
||||
|
||||
:Stivale2 Test (KASLR)
|
||||
@ -54,8 +54,18 @@ MODULE_STRING=yooooo
|
||||
PROTOCOL=stivale2
|
||||
RESOLUTION=640x480x16
|
||||
KASLR=yes
|
||||
KERNEL_PATH=boot:///boot/test.elf
|
||||
KERNEL_CMDLINE=Woah! Another example!
|
||||
|
||||
MODULE_PATH=boot:///boot/bg.bmp
|
||||
MODULE_STRING=yooooo
|
||||
|
||||
:Test bios://
|
||||
|
||||
PROTOCOL=stivale2
|
||||
RESOLUTION=640x480x16
|
||||
KERNEL_PATH=bios://:1/boot/test.elf
|
||||
KERNEL_CMDLINE=Woah! Another example!
|
||||
|
||||
MODULE_PATH=bios://:1/boot/bg.bmp
|
||||
MODULE_STRING=yooooo
|
||||
MODULE_STRING=yooooo
|
Loading…
Reference in New Issue
Block a user