multiboot2: add the basic memory info tag
Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
This commit is contained in:
parent
2b88de7568
commit
0dd2bc6224
|
@ -17,6 +17,13 @@
|
|||
#define MEMMAP_EFI_RECLAIMABLE 0x2000
|
||||
#define MEMMAP_EFI_BOOTSERVICES 0x2001
|
||||
|
||||
struct meminfo {
|
||||
size_t uppermem;
|
||||
size_t lowermem;
|
||||
};
|
||||
|
||||
struct meminfo mmap_get_info(size_t mmap_count, struct e820_entry_t *mmap);
|
||||
|
||||
#if bios == 1
|
||||
extern struct e820_entry_t memmap[];
|
||||
extern size_t memmap_entries;
|
||||
|
|
|
@ -611,6 +611,35 @@ void *ext_mem_alloc_type(size_t count, uint32_t type) {
|
|||
panic("High memory allocator: Out of memory");
|
||||
}
|
||||
|
||||
|
||||
/// Compute and returns the amount of upper and lower memory till
|
||||
/// the first hole.
|
||||
struct meminfo mmap_get_info(size_t mmap_count, struct e820_entry_t *mmap) {
|
||||
struct meminfo info = {0};
|
||||
|
||||
for (size_t i = 0; i < mmap_count; i++) {
|
||||
if (mmap[i].type == MEMMAP_USABLE) {
|
||||
// NOTE: Upper memory starts at address 1MiB and the
|
||||
// value of uppermem is the address of the first upper memory
|
||||
// hole minus 1MiB.
|
||||
if (mmap[i].base < 0x100000) {
|
||||
if (mmap[i].base + mmap[i].length > 0x100000) {
|
||||
size_t low_len = 0x100000 - mmap[i].base;
|
||||
|
||||
info.lowermem += low_len;
|
||||
info.uppermem += mmap[i].length - low_len;
|
||||
} else {
|
||||
info.lowermem += mmap[i].length;
|
||||
}
|
||||
} else {
|
||||
info.uppermem += mmap[i].length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
bool memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free_only, bool do_panic, bool simulation, bool new_entry) {
|
||||
if (length == 0)
|
||||
return true;
|
||||
|
|
|
@ -246,32 +246,22 @@ nofb:;
|
|||
size_t mb_mmap_len = mb_mmap_count * sizeof(struct multiboot1_mmap_entry);
|
||||
struct multiboot1_mmap_entry *mmap = conv_mem_alloc(mb_mmap_len);
|
||||
|
||||
size_t memory_lower = 0, memory_upper = 0;
|
||||
|
||||
// Multiboot is bad and passes raw memmap. We do the same to support it.
|
||||
for (size_t i = 0; i < mb_mmap_count; i++) {
|
||||
mmap[i].size = sizeof(struct multiboot1_mmap_entry) - 4;
|
||||
mmap[i].addr = raw_memmap[i].base;
|
||||
mmap[i].len = raw_memmap[i].length;
|
||||
mmap[i].type = raw_memmap[i].type;
|
||||
|
||||
if (mmap[i].type == MEMMAP_USABLE) {
|
||||
if (mmap[i].addr < 0x100000) {
|
||||
if (mmap[i].addr + mmap[i].len > 0x100000) {
|
||||
size_t low_len = 0x100000 - mmap[i].addr;
|
||||
memory_lower += low_len;
|
||||
memory_upper += mmap[i].len - low_len;
|
||||
} else {
|
||||
memory_lower += mmap[i].len;
|
||||
}
|
||||
} else {
|
||||
memory_upper += mmap[i].len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
multiboot1_info.mem_lower = memory_lower / 1024;
|
||||
multiboot1_info.mem_upper = memory_upper / 1024;
|
||||
{
|
||||
struct meminfo memory_info = mmap_get_info(mb_mmap_count, raw_memmap);
|
||||
|
||||
// Convert the uppermem and lowermem fields from bytes to
|
||||
// KiB.
|
||||
multiboot1_info.mem_lower = memory_info.lowermem / 1024;
|
||||
multiboot1_info.mem_upper = memory_info.uppermem / 1024;
|
||||
}
|
||||
|
||||
multiboot1_info.mmap_length = mb_mmap_len;
|
||||
multiboot1_info.mmap_addr = ((uint32_t)(size_t)mmap);
|
||||
|
|
|
@ -59,6 +59,7 @@ static size_t get_multiboot2_info_size(
|
|||
ALIGN_UP(sizeof(struct multiboot_tag_old_acpi) + 20, MULTIBOOT_TAG_ALIGN) + // old ACPI info
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_elf_sections) + section_hdr_size, MULTIBOOT_TAG_ALIGN) + // ELF info
|
||||
ALIGN_UP(modules_size, MULTIBOOT_TAG_ALIGN) + // modules
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_basic_meminfo), MULTIBOOT_TAG_ALIGN) + // basic memory info
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_mmap) + sizeof(struct multiboot_mmap_entry) * 256, MULTIBOOT_TAG_ALIGN) + // MMAP
|
||||
#if uefi == 1
|
||||
ALIGN_UP(sizeof(struct multiboot_tag_efi_mmap) + (efi_desc_size * 256), MULTIBOOT_TAG_ALIGN) + // EFI MMAP
|
||||
|
@ -120,12 +121,15 @@ void multiboot2_load(char *config, char* cmdline) {
|
|||
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
|
||||
case MULTIBOOT_TAG_TYPE_MODULE:
|
||||
case MULTIBOOT_TAG_TYPE_MMAP:
|
||||
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
|
||||
#if uefi == 1
|
||||
case MULTIBOOT_TAG_TYPE_EFI_MMAP:
|
||||
#if defined (__i386__)
|
||||
case MULTIBOOT_TAG_TYPE_EFI32:
|
||||
case MULTIBOOT_TAG_TYPE_EFI32_IH:
|
||||
#elif defined (__x86_64__)
|
||||
case MULTIBOOT_TAG_TYPE_EFI64:
|
||||
case MULTIBOOT_TAG_TYPE_EFI64_IH:
|
||||
#endif
|
||||
#endif
|
||||
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
|
||||
|
@ -430,7 +434,7 @@ void multiboot2_load(char *config, char* cmdline) {
|
|||
// Create new ACPI info tag
|
||||
//////////////////////////////////////////////
|
||||
{
|
||||
void *new_rsdp = acpi_get_rsdp();
|
||||
void *new_rsdp = acpi_get_rsdp_v2();
|
||||
|
||||
if (new_rsdp != NULL) {
|
||||
uint32_t size = sizeof(struct multiboot_tag_new_acpi) + sizeof(struct rsdp); // XSDP is 36 bytes wide
|
||||
|
@ -518,13 +522,13 @@ void multiboot2_load(char *config, char* cmdline) {
|
|||
efi_exit_boot_services();
|
||||
#endif
|
||||
|
||||
size_t mb_mmap_count;
|
||||
struct e820_entry_t *raw_memmap = get_raw_memmap(&mb_mmap_count);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Create memory map tag
|
||||
//////////////////////////////////////////////
|
||||
{
|
||||
size_t mb_mmap_count;
|
||||
struct e820_entry_t *raw_memmap = get_raw_memmap(&mb_mmap_count);
|
||||
|
||||
if (mb_mmap_count > 256) {
|
||||
panic("multiboot2: too many memory map entries");
|
||||
}
|
||||
|
@ -549,6 +553,24 @@ void multiboot2_load(char *config, char* cmdline) {
|
|||
append_tag(info_idx, mmap_tag);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Create basic memory info tag
|
||||
//////////////////////////////////////////////
|
||||
{
|
||||
struct meminfo meminfo = mmap_get_info(mb_mmap_count, raw_memmap);
|
||||
struct multiboot_tag_basic_meminfo *tag = (struct multiboot_tag_basic_meminfo *)(mb2_info + info_idx);
|
||||
|
||||
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
|
||||
tag->size = sizeof(struct multiboot_tag_basic_meminfo);
|
||||
|
||||
// Convert the uppermem and lowermem fields from bytes to
|
||||
// KiB.
|
||||
tag->mem_upper = (uint32_t)(meminfo.uppermem / 1024);
|
||||
tag->mem_lower = (uint32_t)(meminfo.lowermem / 1024);
|
||||
|
||||
append_tag(info_idx, tag);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Create EFI memory map tag
|
||||
//////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue