mirror of
https://github.com/limine-bootloader/limine
synced 2025-01-11 15:19:29 +03:00
Add GPT support
This commit is contained in:
parent
98086e3829
commit
8680f99eaa
15
Makefile
15
Makefile
@ -10,12 +10,13 @@ echfs-test: all
|
||||
$(MAKE) -C test
|
||||
rm -f test.img
|
||||
dd if=/dev/zero bs=1M count=0 seek=64 of=test.img
|
||||
parted -s test.img mklabel msdos
|
||||
parted -s test.img mkpart primary 1 100%
|
||||
echfs-utils -m -p0 test.img quick-format 32768
|
||||
echfs-utils -m -p0 test.img import test/test.elf test.elf
|
||||
echfs-utils -m -p0 test.img import test/qloader2.cfg qloader2.cfg
|
||||
./qloader2-install src/qloader2.bin test.img
|
||||
parted -s test.img mklabel gpt
|
||||
parted -s test.img mkpart primary 2048s 6143s
|
||||
parted -s test.img mkpart primary 6144s 131038s
|
||||
echfs-utils -g -p1 test.img quick-format 512
|
||||
echfs-utils -g -p1 test.img import test/test.elf test.elf
|
||||
echfs-utils -g -p1 test.img import test/qloader2.cfg qloader2.cfg
|
||||
./qloader2-install src/qloader2.bin test.img 2048
|
||||
qemu-system-x86_64 -hda test.img -monitor stdio
|
||||
|
||||
ext2-test:
|
||||
@ -35,4 +36,4 @@ ext2-test:
|
||||
sudo losetup -d `cat loopback_dev`
|
||||
rm -rf test_image loopback_dev
|
||||
./qloader2-install src/qloader2.bin test.img
|
||||
qemu-system-x86_64 -hda test.img -monitor stdio
|
||||
qemu-system-x86_64 -hda test.img -monitor stdio
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <drivers/disk.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/mbr.h>
|
||||
#include <lib/part.h>
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define BLOCK_SIZE_IN_SECTORS 16
|
||||
@ -74,6 +74,6 @@ int read(int drive, void *buffer, uint64_t loc, uint64_t count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_partition(int drive, struct mbr_part *part, void *buffer, uint64_t loc, uint64_t count) {
|
||||
int read_partition(int drive, struct part *part, void *buffer, uint64_t loc, uint64_t count) {
|
||||
return read(drive, buffer, loc + (part->first_sect * 512), count);
|
||||
}
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <lib/mbr.h>
|
||||
#include <lib/part.h>
|
||||
|
||||
int read(int drive, void *buffer, uint64_t loc, uint64_t count);
|
||||
int read_partition(int drive, struct mbr_part *part, void *buffer, uint64_t loc, uint64_t count);
|
||||
int read_partition(int drive, struct part *part, void *buffer, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
||||
|
@ -24,14 +24,14 @@ static int read_block(struct echfs_file_handle *file, void *buf, uint64_t block,
|
||||
return -1;
|
||||
|
||||
// Read the next block.
|
||||
read_partition(file->disk, &file->mbr_part, &block_val, file->alloc_table_offset + block_val * sizeof(uint64_t),
|
||||
read_partition(file->disk, &file->part, &block_val, file->alloc_table_offset + block_val * sizeof(uint64_t),
|
||||
sizeof(uint64_t));
|
||||
}
|
||||
|
||||
if (block_val == END_OF_CHAIN)
|
||||
return -1;
|
||||
|
||||
return read_partition(file->disk, &file->mbr_part, buf, (block_val * file->block_size) + offset, count);
|
||||
return read_partition(file->disk, &file->part, buf, (block_val * file->block_size) + offset, count);
|
||||
}
|
||||
|
||||
int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count) {
|
||||
@ -51,11 +51,11 @@ int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t
|
||||
}
|
||||
|
||||
int echfs_check_signature(int disk, int partition) {
|
||||
struct mbr_part mbr_part;
|
||||
mbr_get_part(&mbr_part, disk, partition);
|
||||
struct part part;
|
||||
get_part(&part, disk, partition);
|
||||
|
||||
struct echfs_identity_table id_table;
|
||||
read_partition(disk, &mbr_part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
read_partition(disk, &part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
|
||||
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
|
||||
return 0;
|
||||
@ -67,10 +67,10 @@ int echfs_check_signature(int disk, int partition) {
|
||||
int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const char *filename) {
|
||||
ret->disk = disk;
|
||||
|
||||
mbr_get_part(&ret->mbr_part, disk, partition);
|
||||
get_part(&ret->part, disk, partition);
|
||||
|
||||
struct echfs_identity_table id_table;
|
||||
read_partition(disk, &ret->mbr_part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
read_partition(disk, &ret->part, &id_table, 0, sizeof(struct echfs_identity_table));
|
||||
|
||||
if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
|
||||
print("echfs: signature invalid\n", filename);
|
||||
@ -86,7 +86,7 @@ int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const cha
|
||||
|
||||
// Find the file in the root dir.
|
||||
for (uint64_t i = 0; i < ret->dir_length; i += sizeof(struct echfs_dir_entry)) {
|
||||
read_partition(disk, &ret->mbr_part, &ret->dir_entry, i + ret->dir_offset, sizeof(struct echfs_dir_entry));
|
||||
read_partition(disk, &ret->part, &ret->dir_entry, i + ret->dir_offset, sizeof(struct echfs_dir_entry));
|
||||
|
||||
if (!ret->dir_entry.parent_id) {
|
||||
break;
|
||||
@ -101,4 +101,4 @@ int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const cha
|
||||
|
||||
print("echfs: file %s not found\n", filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define __FS__ECHFS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <lib/mbr.h>
|
||||
#include <lib/part.h>
|
||||
|
||||
struct echfs_dir_entry {
|
||||
uint64_t parent_id;
|
||||
@ -20,7 +20,7 @@ struct echfs_dir_entry {
|
||||
|
||||
struct echfs_file_handle {
|
||||
int disk;
|
||||
struct mbr_part mbr_part;
|
||||
struct part part;
|
||||
uint64_t block_size;
|
||||
uint64_t block_count;
|
||||
uint64_t dir_length;
|
||||
|
@ -66,7 +66,7 @@ struct ext2fs_superblock {
|
||||
uint16_t s_state; // state of the filesystem
|
||||
uint16_t s_errors; // what to do incase of an error
|
||||
uint16_t s_minor_rev_level; // combine with major portion to get full version
|
||||
|
||||
|
||||
uint32_t s_lastcheck; // timestamp of last consistency check
|
||||
uint32_t s_checkinterval; // amount of time between required consistency checks
|
||||
uint32_t s_creator_os; // operating system ID
|
||||
@ -104,7 +104,7 @@ struct ext2fs_superblock {
|
||||
uint32_t s_journal_dev; // Journal device
|
||||
uint32_t s_last_orphan; // Head of orphan inode list
|
||||
uint32_t s_hash_seed[4]; // Seeds used for hashing algo for dir indexing
|
||||
|
||||
|
||||
uint8_t s_def_hash_version; // Default hash versrion used for dir indexing
|
||||
|
||||
uint32_t s_default_mnt_opts; // Default mount options
|
||||
@ -122,7 +122,7 @@ struct ext2fs_bgd {
|
||||
uint16_t bg_free_blocks_count; // Number of unallocated blocks in group
|
||||
uint16_t bg_free_inodes_count; // Number of unallocated blocks in inode
|
||||
uint16_t bg_dirs_count; // Number of directories in group
|
||||
|
||||
|
||||
uint16_t reserved[7];
|
||||
} __attribute__((packed));
|
||||
|
||||
@ -184,7 +184,7 @@ struct ext2fs_inode {
|
||||
uint32_t i_ctime; // Time of creation
|
||||
uint32_t i_mtime; // Time of last modification
|
||||
uint32_t i_dtime; // Time of last deletion
|
||||
|
||||
|
||||
uint16_t i_gid; // Block group ID this inode belongs to
|
||||
uint16_t i_links_count; // Number of directory entries in this inode
|
||||
|
||||
@ -193,7 +193,7 @@ struct ext2fs_inode {
|
||||
uint32_t i_osd1; // OS specific value #1 (linux support only) (unused)
|
||||
uint32_t i_blocks[15]; // Block Pointers
|
||||
uint32_t i_generation; // Generation number
|
||||
|
||||
|
||||
/* EXT2 v >= 1.0 */
|
||||
uint32_t i_eab; // Extended Attribute Block
|
||||
uint32_t i_maj; // If feature bit set, upper 32 bit of file size. Directory ACL if inode is directory
|
||||
@ -227,10 +227,10 @@ static struct ext2fs_inode *root_inode;
|
||||
static int num_entries = 0;
|
||||
|
||||
// parse an inode given the partition base and inode number
|
||||
static struct ext2fs_inode *ext2fs_get_inode(uint64_t drive, struct mbr_part *part, uint64_t inode) {
|
||||
static struct ext2fs_inode *ext2fs_get_inode(uint64_t drive, struct part *part, uint64_t inode) {
|
||||
uint64_t base = part->first_sect * 512;
|
||||
uint64_t bgdt_loc = base + EXT2_BLOCK_SIZE;
|
||||
|
||||
|
||||
uint64_t ino_blk_grp = (inode - 1) / superblock->s_inodes_per_group;
|
||||
uint64_t ino_tbl_idx = (inode - 1) % superblock->s_inodes_per_group;
|
||||
|
||||
@ -243,7 +243,7 @@ static struct ext2fs_inode *ext2fs_get_inode(uint64_t drive, struct mbr_part *pa
|
||||
return target;
|
||||
}
|
||||
|
||||
static struct ext2fs_dir_entry *ext2fs_parse_dirent(int drive, struct mbr_part *part, const char* filename) {
|
||||
static struct ext2fs_dir_entry *ext2fs_parse_dirent(int drive, struct part *part, const char* filename) {
|
||||
if (root_inode == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -271,9 +271,9 @@ static struct ext2fs_dir_entry *ext2fs_parse_dirent(int drive, struct mbr_part *
|
||||
}
|
||||
|
||||
int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const char* filename) {
|
||||
struct mbr_part part;
|
||||
mbr_get_part(&part, drive, partition);
|
||||
|
||||
struct part part;
|
||||
get_part(&part, drive, partition);
|
||||
|
||||
struct ext2fs_dir_entry *entry = ext2fs_parse_dirent(drive, &part, filename);
|
||||
|
||||
ret->drive = drive;
|
||||
@ -307,8 +307,8 @@ static int first_run = 0;
|
||||
|
||||
// attempts to initialize the ext2 filesystem
|
||||
int ext2fs_check_signature(int drive, int partition) {
|
||||
struct mbr_part part;
|
||||
mbr_get_part(&part, drive, partition);
|
||||
struct part part;
|
||||
get_part(&part, drive, partition);
|
||||
|
||||
uint64_t base = part.first_sect * 512;
|
||||
|
||||
@ -335,4 +335,4 @@ int ext2fs_check_signature(int drive, int partition) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,11 @@
|
||||
#include <drivers/disk.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/mbr.h>
|
||||
#include <lib/part.h>
|
||||
|
||||
struct ext2fs_file_handle {
|
||||
int drive;
|
||||
struct mbr_part part;
|
||||
struct part part;
|
||||
int inode_num;
|
||||
int size;
|
||||
};
|
||||
@ -20,4 +20,4 @@ int ext2fs_check_signature(int drive, int partition);
|
||||
int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const char* filename);
|
||||
int ext2fs_read(struct ext2fs_file_handle *file, void* buf, uint64_t loc, uint64_t count);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -38,7 +38,7 @@ int fopen(struct file_handle *ret, int disk, int partition, const char *filename
|
||||
return 0;
|
||||
}
|
||||
|
||||
print("fs: Could not determine the file system of disk %u partition %u",
|
||||
print("fs: Could not determine the file system of disk %u partition %u\n",
|
||||
disk, partition);
|
||||
|
||||
return -1;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/real.h>
|
||||
#include <sys/interrupt.h>
|
||||
|
@ -1,34 +0,0 @@
|
||||
#include <lib/mbr.h>
|
||||
#include <drivers/disk.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct mbr_entry {
|
||||
uint8_t status;
|
||||
uint8_t chs_first_sect[3];
|
||||
uint8_t type;
|
||||
uint8_t chs_last_sect[3];
|
||||
uint32_t first_sect;
|
||||
uint32_t sect_count;
|
||||
} __attribute__((packed));
|
||||
|
||||
int mbr_get_part(struct mbr_part *part, int drive, int partition) {
|
||||
// Variables.
|
||||
struct mbr_entry entry;
|
||||
const size_t entry_address = 0x1be + sizeof(struct mbr_entry) * partition;
|
||||
|
||||
// Read the entry of the MBR.
|
||||
int ret;
|
||||
if ((ret = read(drive, &entry, entry_address, sizeof(struct mbr_entry)))) {
|
||||
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;
|
||||
return 0;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#ifndef __MBR_H__
|
||||
#define __MBR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct mbr_part {
|
||||
uint64_t first_sect;
|
||||
uint64_t sect_count;
|
||||
};
|
||||
|
||||
int mbr_get_part(struct mbr_part *part, int drive, int partition);
|
||||
|
||||
#endif
|
128
src/lib/part.c
Normal file
128
src/lib/part.c
Normal file
@ -0,0 +1,128 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <lib/part.h>
|
||||
#include <drivers/disk.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/blib.h>
|
||||
|
||||
#define NO_PARTITION (-1)
|
||||
#define INVALID_TABLE (-2)
|
||||
|
||||
struct gpt_table_header {
|
||||
// the head
|
||||
char signature[8];
|
||||
uint32_t revision;
|
||||
uint32_t header_size;
|
||||
uint32_t crc32;
|
||||
uint32_t _reserved0;
|
||||
|
||||
// the partitioning info
|
||||
uint64_t my_lba;
|
||||
uint64_t alternate_lba;
|
||||
uint64_t first_usable_lba;
|
||||
uint64_t last_usable_lba;
|
||||
|
||||
// the guid
|
||||
struct {
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
} disk_guid;
|
||||
|
||||
// entries related
|
||||
uint64_t partition_entry_lba;
|
||||
uint32_t number_of_partition_entries;
|
||||
uint32_t size_of_partition_entry;
|
||||
uint32_t partition_entry_array_crc32;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct gpt_entry {
|
||||
struct {
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
} partition_type_guid;
|
||||
|
||||
struct {
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
} unique_partition_guid;
|
||||
|
||||
uint64_t starting_lba;
|
||||
uint64_t ending_lba;
|
||||
|
||||
uint64_t attributes;
|
||||
|
||||
uint16_t partition_name[36];
|
||||
} __attribute__((packed));
|
||||
|
||||
static int gpt_get_part(struct part *ret, int drive, int partition) {
|
||||
struct gpt_table_header header = {0};
|
||||
|
||||
// read header, located after the first block
|
||||
read(drive, &header, 512, sizeof(header));
|
||||
|
||||
// check the header
|
||||
// 'EFI PART'
|
||||
if (strncmp(header.signature, "EFI PART", 8)) return INVALID_TABLE;
|
||||
if (header.revision != 0x00010000) return NO_PARTITION;
|
||||
|
||||
// parse the entries if reached here
|
||||
if (partition >= header.number_of_partition_entries) return NO_PARTITION;
|
||||
|
||||
struct gpt_entry entry = {0};
|
||||
read(drive, &entry,
|
||||
(header.partition_entry_lba * 512) + (partition * sizeof(entry)),
|
||||
sizeof(entry));
|
||||
|
||||
if (entry.unique_partition_guid.low == 0 &&
|
||||
entry.unique_partition_guid.high == 0) return NO_PARTITION;
|
||||
|
||||
ret->first_sect = entry.starting_lba;
|
||||
ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mbr_entry {
|
||||
uint8_t status;
|
||||
uint8_t chs_first_sect[3];
|
||||
uint8_t type;
|
||||
uint8_t chs_last_sect[3];
|
||||
uint32_t first_sect;
|
||||
uint32_t sect_count;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int mbr_get_part(struct part *ret, int drive, int partition) {
|
||||
// Variables.
|
||||
struct mbr_entry entry;
|
||||
const size_t entry_address = 0x1be + sizeof(struct mbr_entry) * partition;
|
||||
|
||||
// Read the entry of the MBR.
|
||||
int r;
|
||||
if ((r = read(drive, &entry, entry_address, sizeof(struct mbr_entry)))) {
|
||||
return r;
|
||||
}
|
||||
|
||||
// Check if the partition exists, fail if it doesnt.
|
||||
if (entry.type == 0) {
|
||||
return NO_PARTITION;
|
||||
}
|
||||
|
||||
// Assign the final fields and return.
|
||||
ret->first_sect = entry.first_sect;
|
||||
ret->sect_count = entry.sect_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_part(struct part *part, int drive, int partition) {
|
||||
int ret;
|
||||
|
||||
ret = gpt_get_part(part, drive, partition);
|
||||
if (ret != INVALID_TABLE)
|
||||
return ret;
|
||||
|
||||
ret = mbr_get_part(part, drive, partition);
|
||||
if (ret != INVALID_TABLE)
|
||||
return ret;
|
||||
|
||||
return -1;
|
||||
}
|
13
src/lib/part.h
Normal file
13
src/lib/part.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef __LIB__PART_H__
|
||||
#define __LIB__PART_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct part {
|
||||
uint64_t first_sect;
|
||||
uint64_t sect_count;
|
||||
};
|
||||
|
||||
int get_part(struct part *part, int drive, int partition);
|
||||
|
||||
#endif
|
74
src/main.c
74
src/main.c
@ -9,7 +9,7 @@ asm (
|
||||
#include <lib/real.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/mbr.h>
|
||||
#include <lib/part.h>
|
||||
#include <lib/config.h>
|
||||
#include <fs/file.h>
|
||||
#include <sys/interrupt.h>
|
||||
@ -19,8 +19,6 @@ asm (
|
||||
extern symbol bss_begin;
|
||||
extern symbol bss_end;
|
||||
|
||||
static int config_loaded = 0;
|
||||
|
||||
void main(int boot_drive) {
|
||||
struct file_handle f;
|
||||
|
||||
@ -34,53 +32,49 @@ void main(int boot_drive) {
|
||||
init_idt();
|
||||
|
||||
print("qLoader 2\n\n");
|
||||
print("=> Boot drive: %x\n", boot_drive);
|
||||
print("Boot drive: %x\n", boot_drive);
|
||||
|
||||
// Enumerate partitions.
|
||||
struct mbr_part parts[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
print("=> Checking for partition %d...\n", i);
|
||||
int ret = mbr_get_part(&parts[i], boot_drive, i);
|
||||
// Look for config file.
|
||||
print("Searching for config file...\n");
|
||||
struct part parts[4];
|
||||
for (int i = 0; ; i++) {
|
||||
if (i == 4) {
|
||||
panic("Config file not found.");
|
||||
}
|
||||
print("Checking partition %d...\n", i);
|
||||
int ret = get_part(&parts[i], boot_drive, i);
|
||||
if (ret) {
|
||||
print(" Not found!\n");
|
||||
print("Partition not found.\n");
|
||||
} else {
|
||||
print(" Found!\n");
|
||||
if (!config_loaded) {
|
||||
if (!init_config(boot_drive, i)) {
|
||||
config_loaded = 1;
|
||||
print(" Config file found and loaded!\n");
|
||||
}
|
||||
print("Partition found.\n");
|
||||
if (!init_config(boot_drive, i)) {
|
||||
print("Config file found and loaded.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int drive, part, timeout;
|
||||
char path[128], cmdline[128], proto[64];
|
||||
char path[128], cmdline[128], proto[64], buf[32];
|
||||
|
||||
if (config_loaded) {
|
||||
char buf[32];
|
||||
if (!config_get_value(buf, 0, 32, "KERNEL_DRIVE")) {
|
||||
print("KERNEL_DRIVE not specified, using boot drive (%x)", boot_drive);
|
||||
drive = boot_drive;
|
||||
} else {
|
||||
drive = (int)strtoui(buf);
|
||||
}
|
||||
if (!config_get_value(buf, 0, 64, "TIMEOUT")) {
|
||||
timeout = 5;
|
||||
} else {
|
||||
timeout = (int)strtoui(buf);
|
||||
}
|
||||
config_get_value(buf, 0, 32, "KERNEL_PARTITION");
|
||||
part = (int)strtoui(buf);
|
||||
config_get_value(path, 0, 128, "KERNEL_PATH");
|
||||
config_get_value(cmdline, 0, 128, "KERNEL_CMDLINE");
|
||||
config_get_value(proto, 0, 64, "KERNEL_PROTO");
|
||||
if (!config_get_value(buf, 0, 32, "KERNEL_DRIVE")) {
|
||||
print("KERNEL_DRIVE not specified, using boot drive (%x)", boot_drive);
|
||||
drive = boot_drive;
|
||||
} else {
|
||||
print(" !! NO CONFIG FILE FOUND ON BOOT DRIVE !!");
|
||||
for (;;);
|
||||
drive = (int)strtoui(buf);
|
||||
}
|
||||
if (!config_get_value(buf, 0, 64, "TIMEOUT")) {
|
||||
timeout = 5;
|
||||
} else {
|
||||
timeout = (int)strtoui(buf);
|
||||
}
|
||||
config_get_value(buf, 0, 32, "KERNEL_PARTITION");
|
||||
part = (int)strtoui(buf);
|
||||
config_get_value(path, 0, 128, "KERNEL_PATH");
|
||||
config_get_value(cmdline, 0, 128, "KERNEL_CMDLINE");
|
||||
config_get_value(proto, 0, 64, "KERNEL_PROTO");
|
||||
|
||||
print("\n");
|
||||
print("\n\n");
|
||||
for (int i = timeout; i; i--) {
|
||||
print("\rBooting in %d (press any key to edit command line)...", i);
|
||||
if (pit_sleep_and_quit_on_keypress(18)) {
|
||||
@ -89,7 +83,7 @@ void main(int boot_drive) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print("\n");
|
||||
print("\n\n");
|
||||
|
||||
fopen(&f, drive, part, path);
|
||||
|
||||
@ -109,4 +103,4 @@ void main(int boot_drive) {
|
||||
print("Invalid protocol specified: `%s`.\n", proto);
|
||||
for (;;);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
TIMEOUT=3
|
||||
|
||||
KERNEL_PARTITION=0
|
||||
KERNEL_PARTITION=1
|
||||
KERNEL_PATH=test.elf
|
||||
KERNEL_PROTO=stivale
|
||||
KERNEL_CMDLINE=none
|
||||
|
||||
MODULE_PARTITION=0
|
||||
MODULE_PARTITION=1
|
||||
MODULE_PATH=qloader2.cfg
|
||||
MODULE_STRING=something here
|
||||
|
||||
MODULE_PARTITION=0
|
||||
MODULE_PARTITION=1
|
||||
MODULE_PATH=qloader2.cfg
|
||||
MODULE_STRING=second module
|
||||
|
Loading…
Reference in New Issue
Block a user