mirror of
https://github.com/limine-bootloader/limine
synced 2025-01-21 03:52:04 +03:00
Further work in echfs and partition management
This commit is contained in:
parent
9339c093fe
commit
85d6152025
@ -4,6 +4,7 @@
|
||||
#include <drivers/disk.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/mbr.h>
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
|
||||
@ -77,3 +78,13 @@ int read(int drive, void *buffer, uint64_t loc, uint64_t count) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_partition(int drive, int partition, void *buffer, uint64_t loc, uint64_t count) {
|
||||
struct mbr_part part;
|
||||
int ret = mbr_get_part(&part, drive, partition);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return read(drive, buffer, loc + (part.first_sect * 512), count);
|
||||
}
|
||||
|
@ -6,5 +6,6 @@
|
||||
|
||||
int read_sector(int drive, void *buffer, uint64_t lba, uint64_t count);
|
||||
int read(int drive, void *buffer, uint64_t loc, uint64_t count);
|
||||
int read_partition(int drive, int partition, void *buffer, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
||||
|
74
src/fs/echfs.c
Normal file
74
src/fs/echfs.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include <fs/echfs.h>
|
||||
#include <stdint.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/print.h>
|
||||
|
||||
struct echfs_identity_table {
|
||||
uint8_t jmp[4];
|
||||
uint8_t signature[8];
|
||||
uint64_t block_count;
|
||||
uint64_t dir_length;
|
||||
uint64_t block_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct echfs_dir_entry {
|
||||
uint64_t parent_id;
|
||||
uint8_t type;
|
||||
char name[201];
|
||||
uint64_t atime;
|
||||
uint64_t mtime;
|
||||
uint16_t perms;
|
||||
uint16_t owner;
|
||||
uint16_t group;
|
||||
uint64_t ctime;
|
||||
uint64_t payload;
|
||||
uint64_t size;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define ROOT_DIR_ID (~((uint64_t)0))
|
||||
#define END_OF_CHAIN (~((uint64_t)0))
|
||||
#define FILE_TYPE 0
|
||||
|
||||
int load_echfs_file(int disk, int partition, void *buffer, const char *filename) {
|
||||
// Read the S U P E R B L O C K.
|
||||
struct echfs_identity_table id_table;
|
||||
read_partition(disk, partition, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
|
||||
// Check the signature.
|
||||
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Variables from the table.
|
||||
const uint64_t block_size = id_table.block_size;
|
||||
const uint64_t block_count = id_table.block_count;
|
||||
const uint64_t dir_length = id_table.dir_length;
|
||||
|
||||
// Calculate the offset, jumping the Allocation table and reserved blocks.
|
||||
int offset = (16 * block_size) + (block_count * sizeof(uint64_t) / block_size);
|
||||
|
||||
// Find the file in the root dir.
|
||||
struct echfs_dir_entry entry;
|
||||
for (int i = offset; i < dir_length * block_size; i += sizeof(struct echfs_dir_entry)) {
|
||||
read_partition(disk, partition, &entry, i, sizeof(struct echfs_dir_entry));
|
||||
|
||||
if (!strcmp(filename, entry.name) && entry.parent_id == ROOT_DIR_ID && entry.type == FILE_TYPE) {
|
||||
goto FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
FOUND:;
|
||||
// Load the file.
|
||||
for (uint64_t i = entry.payload; i != END_OF_CHAIN;) {
|
||||
// Read block.
|
||||
read_partition(disk, partition, buffer, i * block_size, block_size);
|
||||
buffer += block_size;
|
||||
|
||||
// Read the next block.
|
||||
read_partition(disk, partition, &i, (16 * block_size) + i * sizeof(uint64_t), sizeof(uint64_t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
6
src/fs/echfs.h
Normal file
6
src/fs/echfs.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __ECHFS_H__
|
||||
#define __ECHFS_H__
|
||||
|
||||
int load_echfs_file(int disk, int partition, void *buffer, const char *filename);
|
||||
|
||||
#endif
|
@ -22,6 +22,11 @@ int mbr_get_part(struct mbr_part *part, int drive, int partition) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check if the partition exists, fail if it doesnt.
|
||||
if (entry.type == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Assign the final fields and return.
|
||||
part->first_sect = entry.first_sect;
|
||||
part->sect_count = entry.sect_count;
|
||||
|
35
src/main.c
35
src/main.c
@ -9,24 +9,53 @@ asm (
|
||||
#include <lib/real.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/types.h>
|
||||
#include <lib/mbr.h>
|
||||
#include <fs/echfs.h>
|
||||
|
||||
extern symbol bss_begin;
|
||||
extern symbol bss_end;
|
||||
|
||||
#define QWORD_KERNEL "qword.bin"
|
||||
|
||||
void main(int boot_drive) {
|
||||
// Zero out .bss section
|
||||
for (uint8_t *p = bss_begin; p < bss_end; p++)
|
||||
*p = 0;
|
||||
|
||||
// Initial prompt.
|
||||
init_vga_textmode();
|
||||
print("qLoader 2\n\n");
|
||||
|
||||
print("=> Boot drive: %x\n\n", boot_drive);
|
||||
|
||||
for (;;) {
|
||||
// Enumerate partitions.
|
||||
struct mbr_part parts[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
print("=> Checking for partition %d...", i);
|
||||
int ret = mbr_get_part(&parts[i], boot_drive, i);
|
||||
if (ret) {
|
||||
print("Not found!\n");
|
||||
} else {
|
||||
print("Found!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Load the file from the chooen partition at 1 MiB.
|
||||
int part = 1; // TODO: The boot partition is hardcoded for now.
|
||||
print("=> Booting %s in partition %d\n", QWORD_KERNEL, part);
|
||||
load_echfs_file(boot_drive, part, (void *)0x100000, QWORD_KERNEL);
|
||||
|
||||
// Boot the kernel.
|
||||
asm volatile (
|
||||
"jmp 0x100000"
|
||||
:
|
||||
: "b" ("")
|
||||
: "memory"
|
||||
);
|
||||
|
||||
/*for (;;) {
|
||||
struct rm_regs r = {0};
|
||||
rm_int(0x16, &r, &r); // Real mode interrupt 16h
|
||||
char c = (char)(r.eax & 0xff);
|
||||
text_write(&c, 1);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user