mirror of
https://github.com/limine-bootloader/limine
synced 2024-11-27 11:00:28 +03:00
Add out of memory checks
This commit is contained in:
parent
adb083e107
commit
62d78d1f90
BIN
qloader2.bin
BIN
qloader2.bin
Binary file not shown.
@ -7,6 +7,25 @@
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/cio.h>
|
||||
#include <lib/e820.h>
|
||||
|
||||
// Checks if a given memory range is entirely within a usable e820 entry.
|
||||
// TODO: Consider the possibility of adjacent usable entries.
|
||||
// TODO: Consider the possibility of usable entry being overlapped by non-usable
|
||||
// ones.
|
||||
void is_valid_memory_range(size_t base, size_t size) {
|
||||
for (size_t i = 0; i < e820_entries; i++) {
|
||||
if (e820_map[i].type != 1)
|
||||
continue;
|
||||
size_t entry_base = e820_map[i].base;
|
||||
size_t entry_top = e820_map[i].base + e820_map[i].length;
|
||||
size_t limit = base + size;
|
||||
if (base >= entry_base && base < entry_top &&
|
||||
limit >= entry_base && limit < entry_top)
|
||||
return;
|
||||
}
|
||||
panic("Out of memory");
|
||||
}
|
||||
|
||||
uint8_t bcd_to_int(uint8_t val) {
|
||||
return (val & 0x0f) + ((val & 0xf0) >> 4) * 10;
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void is_valid_memory_range(size_t base, size_t size);
|
||||
|
||||
uint8_t bcd_to_int(uint8_t val);
|
||||
|
||||
int cpuid(uint32_t leaf, uint32_t subleaf,
|
||||
|
@ -1,8 +1,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <lib/e820.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/blib.h>
|
||||
|
||||
struct e820_entry_t *e820_map;
|
||||
size_t e820_entries;
|
||||
|
||||
static const char *e820_type(uint32_t type) {
|
||||
switch (type) {
|
||||
@ -21,13 +24,11 @@ static const char *e820_type(uint32_t type) {
|
||||
}
|
||||
}
|
||||
|
||||
int init_e820(void) {
|
||||
void init_e820(void) {
|
||||
struct rm_regs r = {0};
|
||||
|
||||
int entry_count;
|
||||
|
||||
e820_map = balloc(sizeof(struct e820_entry_t));
|
||||
for (int i = 0; ; i++) {
|
||||
for (size_t i = 0; ; i++) {
|
||||
struct e820_entry_t entry;
|
||||
|
||||
r.eax = 0xe820;
|
||||
@ -39,25 +40,23 @@ int init_e820(void) {
|
||||
e820_map[i] = entry;
|
||||
|
||||
if (r.eflags & EFLAGS_CF) {
|
||||
entry_count = i;
|
||||
e820_entries = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!r.ebx) {
|
||||
entry_count = ++i;
|
||||
e820_entries = ++i;
|
||||
break;
|
||||
}
|
||||
|
||||
balloc(sizeof(struct e820_entry_t));
|
||||
}
|
||||
|
||||
for (int i = 0; i < entry_count; i++) {
|
||||
for (size_t i = 0; i < e820_entries; i++) {
|
||||
print("e820: [%X -> %X] : %X <%s>\n",
|
||||
e820_map[i].base,
|
||||
e820_map[i].base + e820_map[i].length,
|
||||
e820_map[i].length,
|
||||
e820_type(e820_map[i].type));
|
||||
}
|
||||
|
||||
return entry_count;
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
#define __LIB__E820_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define E820_MAX_ENTRIES 256
|
||||
#include <stddef.h>
|
||||
|
||||
struct e820_entry_t {
|
||||
uint64_t base;
|
||||
@ -13,7 +12,8 @@ struct e820_entry_t {
|
||||
} __attribute__((packed));
|
||||
|
||||
extern struct e820_entry_t *e820_map;
|
||||
extern size_t e820_entries;
|
||||
|
||||
int init_e820(void);
|
||||
void init_e820(void);
|
||||
|
||||
#endif
|
||||
|
@ -243,8 +243,9 @@ int elf64_load(struct file_handle *fd, uint64_t *entry_point, uint64_t *top) {
|
||||
if (this_top > *top)
|
||||
*top = this_top;
|
||||
|
||||
fread(fd, (void *)(uint32_t)phdr.p_vaddr,
|
||||
phdr.p_offset, phdr.p_filesz);
|
||||
is_valid_memory_range((size_t)phdr.p_vaddr, (size_t)phdr.p_memsz);
|
||||
|
||||
fread(fd, (void *)(uint32_t)phdr.p_vaddr, phdr.p_offset, phdr.p_filesz);
|
||||
|
||||
size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);
|
||||
|
||||
@ -292,6 +293,8 @@ int elf32_load(struct file_handle *fd, uint32_t *entry_point, uint32_t *top) {
|
||||
if (this_top > *top)
|
||||
*top = this_top;
|
||||
|
||||
is_valid_memory_range((size_t)phdr.p_paddr, (size_t)phdr.p_memsz);
|
||||
|
||||
fread(fd, (void *)phdr.p_paddr, phdr.p_offset, phdr.p_filesz);
|
||||
|
||||
size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);
|
||||
|
@ -20,6 +20,7 @@ asm (
|
||||
#include <lib/libc.h>
|
||||
#include <lib/part.h>
|
||||
#include <lib/config.h>
|
||||
#include <lib/e820.h>
|
||||
#include <fs/file.h>
|
||||
#include <lib/elf.h>
|
||||
#include <protos/stivale.h>
|
||||
@ -149,6 +150,8 @@ void main(int boot_drive) {
|
||||
}
|
||||
|
||||
got_entry:
|
||||
init_e820();
|
||||
|
||||
if (!config_get_value(buf, 0, 32, "KERNEL_DRIVE")) {
|
||||
drive = boot_drive;
|
||||
} else {
|
||||
|
@ -7,6 +7,9 @@
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/config.h>
|
||||
|
||||
#define KERNEL_LOAD_ADDR ((size_t)0x100000)
|
||||
#define INITRD_LOAD_ADDR ((size_t)0x1000000)
|
||||
|
||||
void linux_load(struct file_handle *fd, char *cmdline) {
|
||||
uint32_t signature;
|
||||
fread(fd, &signature, 0x202, sizeof(uint32_t));
|
||||
@ -70,7 +73,8 @@ void linux_load(struct file_handle *fd, char *cmdline) {
|
||||
|
||||
// load kernel
|
||||
print("Loading kernel...\n");
|
||||
fread(fd, (void *)0x100000, real_mode_code_size, fd->size - real_mode_code_size);
|
||||
is_valid_memory_range(KERNEL_LOAD_ADDR, fd->size - real_mode_code_size);
|
||||
fread(fd, (void *)KERNEL_LOAD_ADDR, real_mode_code_size, fd->size - real_mode_code_size);
|
||||
|
||||
char initrd_path[64];
|
||||
if (!config_get_value(initrd_path, 0, 64, "INITRD_PATH"))
|
||||
@ -88,10 +92,10 @@ void linux_load(struct file_handle *fd, char *cmdline) {
|
||||
}
|
||||
|
||||
print("Loading initrd...\n");
|
||||
size_t initrd_addr = 0x1000000;
|
||||
fread(&initrd, (void *)initrd_addr, 0, initrd.size);
|
||||
is_valid_memory_range(INITRD_LOAD_ADDR, initrd.size);
|
||||
fread(&initrd, (void *)INITRD_LOAD_ADDR, 0, initrd.size);
|
||||
|
||||
*((uint32_t *)(real_mode_code + 0x218)) = (uint32_t)initrd_addr;
|
||||
*((uint32_t *)(real_mode_code + 0x218)) = (uint32_t)INITRD_LOAD_ADDR;
|
||||
*((uint32_t *)(real_mode_code + 0x21c)) = (uint32_t)initrd.size;
|
||||
|
||||
uint16_t real_mode_code_seg = rm_seg(real_mode_code);
|
||||
|
@ -97,7 +97,7 @@ void stivale_load(struct file_handle *fd, char *cmdline) {
|
||||
|
||||
print("stivale: Top used address in ELF: %X\n", top_used_addr);
|
||||
|
||||
stivale_struct.memory_map_entries = (uint64_t)init_e820();
|
||||
stivale_struct.memory_map_entries = (uint64_t)e820_entries;
|
||||
stivale_struct.memory_map_addr = (uint64_t)(size_t)e820_map;
|
||||
|
||||
stivale_struct.module_count = 0;
|
||||
@ -126,6 +126,7 @@ void stivale_load(struct file_handle *fd, char *cmdline) {
|
||||
((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
|
||||
(uint32_t)top_used_addr);
|
||||
|
||||
is_valid_memory_range((size_t)module_addr, f.size);
|
||||
fread(&f, module_addr, 0, f.size);
|
||||
|
||||
m->begin = (uint64_t)(size_t)module_addr;
|
||||
|
Loading…
Reference in New Issue
Block a user