Some general cleanup
This commit is contained in:
parent
0319b51b4b
commit
c542ff6845
BIN
limine.bin
BIN
limine.bin
Binary file not shown.
@ -1,93 +1,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/real.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/e820.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/config.h>
|
||||
#include <lib/part.h>
|
||||
#include <mm/pmm.h>
|
||||
|
||||
uint8_t boot_drive;
|
||||
|
||||
// BIOS partitions are specified in the <BIOS drive>:<partition> form.
|
||||
// The drive may be omitted, the partition cannot.
|
||||
static bool parse_bios_partition(char *loc, uint8_t *drive, uint8_t *partition) {
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (loc[i] == 0)
|
||||
return false;
|
||||
|
||||
if (loc[i] == ':') {
|
||||
loc[i] = 0;
|
||||
if (*loc == 0) {
|
||||
*drive = boot_drive;
|
||||
} else {
|
||||
if (strtoui(loc) < 1 || strtoui(loc) > 16) {
|
||||
panic("BIOS drive number outside range 1-16");
|
||||
}
|
||||
*drive = (strtoui(loc) - 1) + 0x80;
|
||||
}
|
||||
loc += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*loc == 0)
|
||||
return false;
|
||||
|
||||
if (strtoui(loc) < 1 || strtoui(loc) > 256) {
|
||||
panic("BIOS partition number outside range 1-256");
|
||||
}
|
||||
*partition = strtoui(loc) - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
|
||||
uint8_t drive, partition;
|
||||
|
||||
if (!parse_bios_partition(loc, &drive, &partition))
|
||||
return false;
|
||||
|
||||
if (fopen(fd, drive, partition, path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool uri_guid_dispatch(struct file_handle *fd, char *guid_str, char *path) {
|
||||
struct guid guid;
|
||||
if (!string_to_guid(&guid, guid_str))
|
||||
return false;
|
||||
|
||||
int drive, partition;
|
||||
if (!part_get_by_guid(&drive, &partition, &guid))
|
||||
return false;
|
||||
|
||||
if (fopen(fd, drive, partition, path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uri_open(struct file_handle *fd, char *uri) {
|
||||
char *resource, *root, *path;
|
||||
config_resolve_uri(uri, &resource, &root, &path);
|
||||
|
||||
if (!strcmp(resource, "bios")) {
|
||||
return uri_bios_dispatch(fd, root, path);
|
||||
} else if (!strcmp(resource, "guid")) {
|
||||
return uri_guid_dispatch(fd, root, path);
|
||||
} else {
|
||||
panic("Resource `%s` not valid.", resource);
|
||||
}
|
||||
}
|
||||
|
||||
// This integer sqrt implementation has been adapted from:
|
||||
// https://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2
|
||||
uint64_t sqrt(uint64_t a_nInput) {
|
||||
@ -133,7 +51,7 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
static int char_value(char c) {
|
||||
int digit_to_int(char c) {
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
return (c - 'a') + 10;
|
||||
}
|
||||
@ -147,89 +65,16 @@ static int char_value(char c) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool is_valid_guid(const char *s) {
|
||||
for (size_t i = 0; ; i++) {
|
||||
switch (i) {
|
||||
case 8:
|
||||
case 13:
|
||||
case 18:
|
||||
case 23:
|
||||
if (s[i] != '-')
|
||||
return false;
|
||||
break;
|
||||
case 36:
|
||||
return s[i] == 0;
|
||||
default:
|
||||
if (char_value(s[i]) == -1)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
|
||||
size_t p = 0;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
int val = char_value(s[i]);
|
||||
|
||||
i % 2 ? (dest[p] = val) : (dest[p++] |= val << 4);
|
||||
}
|
||||
}
|
||||
*/
|
||||
static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) {
|
||||
size_t p = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int val = char_value(s[i]);
|
||||
|
||||
i % 2 ? (dest[p++] |= val) : (dest[p] = val << 4);
|
||||
}
|
||||
}
|
||||
|
||||
bool string_to_guid(struct guid *guid, const char *s) {
|
||||
if (!is_valid_guid(s))
|
||||
return false;
|
||||
|
||||
guid_convert_be_cluster((uint8_t *)guid + 0, s + 0, 8);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 4, s + 9, 4);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 6, s + 14, 4);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 8, s + 19, 4);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t strtoui(const char *s) {
|
||||
uint64_t n = 0;
|
||||
while (*s)
|
||||
n = n * 10 + char_value(*(s++));
|
||||
n = n * 10 + digit_to_int(*(s++));
|
||||
return n;
|
||||
}
|
||||
|
||||
uint64_t strtoui16(const char *s) {
|
||||
uint64_t n = 0;
|
||||
while (*s)
|
||||
n = n * 16 + char_value(*(s++));
|
||||
n = n * 16 + digit_to_int(*(s++));
|
||||
return n;
|
||||
}
|
||||
|
||||
int getchar_internal(uint32_t eax) {
|
||||
switch ((eax >> 8) & 0xff) {
|
||||
case 0x4b:
|
||||
return GETCHAR_CURSOR_LEFT;
|
||||
case 0x4d:
|
||||
return GETCHAR_CURSOR_RIGHT;
|
||||
case 0x48:
|
||||
return GETCHAR_CURSOR_UP;
|
||||
case 0x50:
|
||||
return GETCHAR_CURSOR_DOWN;
|
||||
case 0x53:
|
||||
return GETCHAR_DELETE;
|
||||
}
|
||||
return (char)(eax & 0xff);
|
||||
}
|
||||
|
||||
int getchar(void) {
|
||||
struct rm_regs r = {0};
|
||||
rm_int(0x16, &r, &r);
|
||||
return getchar_internal(r.eax);
|
||||
}
|
||||
|
@ -4,36 +4,18 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <fs/file.h>
|
||||
|
||||
extern uint8_t boot_drive;
|
||||
|
||||
struct guid {
|
||||
uint32_t a;
|
||||
uint16_t b;
|
||||
uint16_t c;
|
||||
uint8_t d[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
bool string_to_guid(struct guid *guid, const char *s);
|
||||
|
||||
bool uri_open(struct file_handle *fd, char *uri);
|
||||
|
||||
uint64_t sqrt(uint64_t a_nInput);
|
||||
|
||||
int digit_to_int(char c);
|
||||
uint8_t bcd_to_int(uint8_t val);
|
||||
|
||||
__attribute__((noreturn)) void panic(const char *fmt, ...);
|
||||
|
||||
int pit_sleep_and_quit_on_keypress(uint32_t pit_ticks);
|
||||
|
||||
#define GETCHAR_CURSOR_LEFT (-10)
|
||||
#define GETCHAR_CURSOR_RIGHT (-11)
|
||||
#define GETCHAR_CURSOR_UP (-12)
|
||||
#define GETCHAR_CURSOR_DOWN (-13)
|
||||
#define GETCHAR_DELETE (-14)
|
||||
|
||||
int getchar(void);
|
||||
uint64_t strtoui(const char *s);
|
||||
uint64_t strtoui16(const char *s);
|
||||
|
||||
|
@ -121,42 +121,3 @@ char *config_get_value(char *buf, size_t index, size_t limit, const char *key) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// A URI takes the form of: resource://root/path
|
||||
// The following function splits up a URI into its componenets
|
||||
bool config_resolve_uri(char *uri, char **resource, char **root, char **path) {
|
||||
*resource = *root = *path = NULL;
|
||||
|
||||
// Get resource
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (strlen(uri + i) < 3)
|
||||
return false;
|
||||
|
||||
if (!memcmp(uri + i, "://", 3)) {
|
||||
*resource = uri;
|
||||
uri[i] = 0;
|
||||
uri += i + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get root
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (uri[i] == 0)
|
||||
return false;
|
||||
|
||||
if (uri[i] == '/') {
|
||||
*root = uri;
|
||||
uri[i] = 0;
|
||||
uri += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get path
|
||||
if (*uri == 0)
|
||||
return false;
|
||||
*path = uri;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -10,6 +10,5 @@ int init_config(int drive, int part);
|
||||
int config_get_entry_name(char *ret, size_t index, size_t limit);
|
||||
int config_set_entry(size_t index);
|
||||
char *config_get_value(char *buf, size_t index, size_t limit, const char *key);
|
||||
bool config_resolve_uri(char *uri, char **resource, char **root, char **path);
|
||||
|
||||
#endif
|
||||
|
58
stage2/lib/guid.c
Normal file
58
stage2/lib/guid.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <lib/guid.h>
|
||||
#include <lib/blib.h>
|
||||
|
||||
bool is_valid_guid(const char *s) {
|
||||
for (size_t i = 0; ; i++) {
|
||||
switch (i) {
|
||||
case 8:
|
||||
case 13:
|
||||
case 18:
|
||||
case 23:
|
||||
if (s[i] != '-')
|
||||
return false;
|
||||
break;
|
||||
case 36:
|
||||
return s[i] == 0;
|
||||
default:
|
||||
if (digit_to_int(s[i]) == -1)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
|
||||
size_t p = 0;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
int val = digit_to_int(s[i]);
|
||||
|
||||
i % 2 ? (dest[p] = val) : (dest[p++] |= val << 4);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) {
|
||||
size_t p = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int val = digit_to_int(s[i]);
|
||||
|
||||
i % 2 ? (dest[p++] |= val) : (dest[p] = val << 4);
|
||||
}
|
||||
}
|
||||
|
||||
bool string_to_guid(struct guid *guid, const char *s) {
|
||||
if (!is_valid_guid(s))
|
||||
return false;
|
||||
|
||||
guid_convert_be_cluster((uint8_t *)guid + 0, s + 0, 8);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 4, s + 9, 4);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 6, s + 14, 4);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 8, s + 19, 4);
|
||||
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
|
||||
|
||||
return true;
|
||||
}
|
17
stage2/lib/guid.h
Normal file
17
stage2/lib/guid.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef __LIB__GUID_H__
|
||||
#define __LIB__GUID_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct guid {
|
||||
uint32_t a;
|
||||
uint16_t b;
|
||||
uint16_t c;
|
||||
uint8_t d[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
bool is_valid_guid(const char *s);
|
||||
bool string_to_guid(struct guid *guid, const char *s);
|
||||
|
||||
#endif
|
@ -7,6 +7,7 @@
|
||||
#include <lib/real.h>
|
||||
#include <lib/print.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <fs/file.h>
|
||||
|
||||
#define NO_PARTITION (-1)
|
||||
#define INVALID_TABLE (-2)
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/guid.h>
|
||||
|
||||
struct part {
|
||||
int drive;
|
||||
|
@ -4,6 +4,29 @@
|
||||
#include <lib/libc.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/real.h>
|
||||
|
||||
int getchar_internal(uint32_t eax) {
|
||||
switch ((eax >> 8) & 0xff) {
|
||||
case 0x4b:
|
||||
return GETCHAR_CURSOR_LEFT;
|
||||
case 0x4d:
|
||||
return GETCHAR_CURSOR_RIGHT;
|
||||
case 0x48:
|
||||
return GETCHAR_CURSOR_UP;
|
||||
case 0x50:
|
||||
return GETCHAR_CURSOR_DOWN;
|
||||
case 0x53:
|
||||
return GETCHAR_DELETE;
|
||||
}
|
||||
return (char)(eax & 0xff);
|
||||
}
|
||||
|
||||
int getchar(void) {
|
||||
struct rm_regs r = {0};
|
||||
rm_int(0x16, &r, &r);
|
||||
return getchar_internal(r.eax);
|
||||
}
|
||||
|
||||
static void reprint_string(int x, int y, const char *s) {
|
||||
int orig_x, orig_y;
|
||||
|
@ -3,6 +3,13 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define GETCHAR_CURSOR_LEFT (-10)
|
||||
#define GETCHAR_CURSOR_RIGHT (-11)
|
||||
#define GETCHAR_CURSOR_UP (-12)
|
||||
#define GETCHAR_CURSOR_DOWN (-13)
|
||||
#define GETCHAR_DELETE (-14)
|
||||
|
||||
int getchar(void);
|
||||
void readline(const char *orig_str, char *buf, size_t limit);
|
||||
|
||||
#endif
|
||||
|
119
stage2/lib/uri.c
Normal file
119
stage2/lib/uri.c
Normal file
@ -0,0 +1,119 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <lib/uri.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/part.h>
|
||||
#include <lib/libc.h>
|
||||
#include <fs/file.h>
|
||||
|
||||
// A URI takes the form of: resource://root/path
|
||||
// The following function splits up a URI into its componenets
|
||||
bool uri_resolve(char *uri, char **resource, char **root, char **path) {
|
||||
*resource = *root = *path = NULL;
|
||||
|
||||
// Get resource
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (strlen(uri + i) < 3)
|
||||
return false;
|
||||
|
||||
if (!memcmp(uri + i, "://", 3)) {
|
||||
*resource = uri;
|
||||
uri[i] = 0;
|
||||
uri += i + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get root
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (uri[i] == 0)
|
||||
return false;
|
||||
|
||||
if (uri[i] == '/') {
|
||||
*root = uri;
|
||||
uri[i] = 0;
|
||||
uri += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get path
|
||||
if (*uri == 0)
|
||||
return false;
|
||||
*path = uri;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// BIOS partitions are specified in the <BIOS drive>:<partition> form.
|
||||
// The drive may be omitted, the partition cannot.
|
||||
static bool parse_bios_partition(char *loc, uint8_t *drive, uint8_t *partition) {
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (loc[i] == 0)
|
||||
return false;
|
||||
|
||||
if (loc[i] == ':') {
|
||||
loc[i] = 0;
|
||||
if (*loc == 0) {
|
||||
*drive = boot_drive;
|
||||
} else {
|
||||
if (strtoui(loc) < 1 || strtoui(loc) > 16) {
|
||||
panic("BIOS drive number outside range 1-16");
|
||||
}
|
||||
*drive = (strtoui(loc) - 1) + 0x80;
|
||||
}
|
||||
loc += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*loc == 0)
|
||||
return false;
|
||||
|
||||
if (strtoui(loc) < 1 || strtoui(loc) > 256) {
|
||||
panic("BIOS partition number outside range 1-256");
|
||||
}
|
||||
*partition = strtoui(loc) - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
|
||||
uint8_t drive, partition;
|
||||
|
||||
if (!parse_bios_partition(loc, &drive, &partition))
|
||||
return false;
|
||||
|
||||
if (fopen(fd, drive, partition, path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool uri_guid_dispatch(struct file_handle *fd, char *guid_str, char *path) {
|
||||
struct guid guid;
|
||||
if (!string_to_guid(&guid, guid_str))
|
||||
return false;
|
||||
|
||||
int drive, partition;
|
||||
if (!part_get_by_guid(&drive, &partition, &guid))
|
||||
return false;
|
||||
|
||||
if (fopen(fd, drive, partition, path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uri_open(struct file_handle *fd, char *uri) {
|
||||
char *resource, *root, *path;
|
||||
uri_resolve(uri, &resource, &root, &path);
|
||||
|
||||
if (!strcmp(resource, "bios")) {
|
||||
return uri_bios_dispatch(fd, root, path);
|
||||
} else if (!strcmp(resource, "guid")) {
|
||||
return uri_guid_dispatch(fd, root, path);
|
||||
} else {
|
||||
panic("Resource `%s` not valid.", resource);
|
||||
}
|
||||
}
|
10
stage2/lib/uri.h
Normal file
10
stage2/lib/uri.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __LIB__URI_H__
|
||||
#define __LIB__URI_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <fs/file.h>
|
||||
|
||||
bool uri_resolve(char *uri, char **resource, char **root, char **path);
|
||||
bool uri_open(struct file_handle *fd, char *uri);
|
||||
|
||||
#endif
|
@ -9,6 +9,7 @@
|
||||
#include <lib/config.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/readline.h>
|
||||
#include <lib/uri.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <drivers/vbe.h>
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <lib/term.h>
|
||||
#include <lib/config.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/uri.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/mtrr.h>
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <lib/print.h>
|
||||
#include <lib/rand.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/uri.h>
|
||||
#include <drivers/vbe.h>
|
||||
#include <lib/term.h>
|
||||
#include <sys/pic.h>
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <lib/rand.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/libc.h>
|
||||
#include <lib/uri.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <drivers/vbe.h>
|
||||
|
Loading…
Reference in New Issue
Block a user