Build new page tables in HULK
This commit is contained in:
parent
c8a81b1101
commit
c11361d40f
@ -58,7 +58,7 @@ struct acpi
|
||||
public static void initialize(ulong acpi_xsdt_phys)
|
||||
{
|
||||
/* Map the XSDT header. */
|
||||
hurl.map_range(acpi_xsdt_phys, Xsdt.sizeof, 0u);
|
||||
hurl.identity_map_range(acpi_xsdt_phys, Xsdt.sizeof, 0u);
|
||||
const(Xsdt) * xsdt = cast(const(Xsdt) *)acpi_xsdt_phys;
|
||||
if (xsdt.header.signature != XSDT_SIGNATURE)
|
||||
{
|
||||
@ -66,12 +66,12 @@ struct acpi
|
||||
return;
|
||||
}
|
||||
/* Map the entire XSDT. */
|
||||
hurl.map_range(acpi_xsdt_phys, xsdt.header.length, 0u);
|
||||
hurl.identity_map_range(acpi_xsdt_phys, xsdt.header.length, 0u);
|
||||
size_t n_entries = (xsdt.header.length - xsdt.header.sizeof) / xsdt.tables[0].sizeof;
|
||||
for (size_t i = 0u; i < n_entries; i++)
|
||||
{
|
||||
ulong address = xsdt.tables[i];
|
||||
hurl.map_range(address, 4u, 0u);
|
||||
hurl.identity_map_range(address, 4u, 0u);
|
||||
uint signature = *cast(const(uint) *)address;
|
||||
if (signature == APIC_SIGNATURE)
|
||||
{
|
||||
@ -83,7 +83,7 @@ struct acpi
|
||||
private static parse_apic_table(ulong address)
|
||||
{
|
||||
const(MadtHeader) * madt_header = cast(const(MadtHeader) *)address;
|
||||
hurl.map_range(address, madt_header.length, 0u);
|
||||
hurl.identity_map_range(address, madt_header.length, 0u);
|
||||
apic_address = madt_header.local_apic_address;
|
||||
klog.writefln("Found 32-bit APIC address: 0x%x", apic_address);
|
||||
const(void) * madt_end = cast(const(void) *)(address + madt_header.length);
|
||||
|
@ -31,6 +31,11 @@ struct hippo
|
||||
*/
|
||||
private static __gshared size_t n_free_pages;
|
||||
|
||||
/**
|
||||
* Physical address limit.
|
||||
*/
|
||||
public static __gshared size_t physical_address_limit;
|
||||
|
||||
/**
|
||||
* Initialize HIPPO.
|
||||
*
|
||||
@ -54,7 +59,7 @@ struct hippo
|
||||
[header.bootinfo.hulk_phys, cast(ulong)header.total_size - LinkerAddresses.hulk_bss_size],
|
||||
[header.bootinfo.bss_phys, LinkerAddresses.hulk_bss_size],
|
||||
[header.bootinfo.stack_phys, header.stack_size],
|
||||
[cast(ulong)header.bootinfo.fb.buffer, header.bootinfo.fb.height * header.bootinfo.fb.stride],
|
||||
[cast(ulong)header.bootinfo.fb.buffer, header.bootinfo.fb.height * header.bootinfo.fb.stride * 4u],
|
||||
[header.bootinfo.pt_phys, header.bootinfo.pt_size],
|
||||
];
|
||||
for (size_t ri = 0u; ri < reserved.length; ri++)
|
||||
@ -67,6 +72,10 @@ struct hippo
|
||||
{
|
||||
ulong phys = header.bootinfo.memory_map[bii].base;
|
||||
ulong phys_end = phys + header.bootinfo.memory_map[bii].size;
|
||||
if (phys_end > physical_address_limit)
|
||||
{
|
||||
physical_address_limit = phys_end;
|
||||
}
|
||||
usable_memory += header.bootinfo.memory_map[bii].size;
|
||||
while (phys < phys_end)
|
||||
{
|
||||
|
@ -41,7 +41,6 @@ void hulk_start()
|
||||
cli();
|
||||
gdt.initialize();
|
||||
idt.initialize();
|
||||
hurl.initialize();
|
||||
fb.initialize(cast(uint *)HULK_VIRTUAL_FRAMEBUFFER_ADDRESS, hulk_header.bootinfo.fb.width, hulk_header.bootinfo.fb.height, hulk_header.bootinfo.fb.stride);
|
||||
console.initialize();
|
||||
console.clear();
|
||||
@ -50,6 +49,7 @@ void hulk_start()
|
||||
klog.writefln("Welcome to HULK, the HOS UltraLight Kernel!");
|
||||
|
||||
hippo.initialize(&hulk_header);
|
||||
hurl.initialize(&hulk_header);
|
||||
pci.initialize();
|
||||
pic.initialize();
|
||||
acpi.initialize(hulk_header.bootinfo.acpi_xsdt_phys);
|
||||
|
@ -9,6 +9,8 @@ import hos.cpu;
|
||||
import hulk.hippo;
|
||||
import hos.memory;
|
||||
import hulk.klog;
|
||||
import hulk.header;
|
||||
import hulk.linker_addresses;
|
||||
|
||||
/** HULK virtual base address. */
|
||||
enum ulong HULK_VIRTUAL_BASE_ADDRESS = 0xFFFF_8000_0000_0000u;
|
||||
@ -91,18 +93,49 @@ struct hurl
|
||||
|
||||
private static __gshared PageTable * m_pt_base;
|
||||
|
||||
public static void initialize()
|
||||
/**
|
||||
* Initialize HURL.
|
||||
*
|
||||
* @param bootinfo HULK boot information structure.
|
||||
*/
|
||||
public static void initialize(HulkHeader * header)
|
||||
{
|
||||
m_pt_base = cast(PageTable *)read_cr3();
|
||||
m_pt_base = allocate_pt();
|
||||
size_t hulk_bin_phys_size = cast(ulong)header.total_size - LinkerAddresses.hulk_bss_size;
|
||||
/* Identity map all physical RAM. */
|
||||
map_range(0u,
|
||||
0u,
|
||||
hippo.physical_address_limit,
|
||||
MAP_WRITABLE | MAP_NO_EXECUTE);
|
||||
/* Map HULK binary region. */
|
||||
map_range(HULK_VIRTUAL_BASE_ADDRESS,
|
||||
header.bootinfo.hulk_phys,
|
||||
hulk_bin_phys_size,
|
||||
MAP_WRITABLE);
|
||||
/* Map HULK BSS region. */
|
||||
map_range(HULK_VIRTUAL_BASE_ADDRESS + hulk_bin_phys_size,
|
||||
header.bootinfo.bss_phys,
|
||||
LinkerAddresses.hulk_bss_size,
|
||||
MAP_WRITABLE | MAP_NO_EXECUTE);
|
||||
/* Map HULK stack. */
|
||||
map_range(HULK_VIRTUAL_STACK_TOP_ADDRESS - header.stack_size,
|
||||
header.bootinfo.stack_phys,
|
||||
header.stack_size,
|
||||
MAP_WRITABLE | MAP_NO_EXECUTE);
|
||||
/* Map HULK framebuffer. */
|
||||
map_range(HULK_VIRTUAL_FRAMEBUFFER_ADDRESS,
|
||||
cast(ulong)header.bootinfo.fb.buffer,
|
||||
header.bootinfo.fb.height * header.bootinfo.fb.stride * 4u,
|
||||
MAP_WRITABLE | MAP_NO_EXECUTE);
|
||||
write_cr3(cast(ulong)m_pt_base);
|
||||
}
|
||||
|
||||
public static void map(ulong virtual, ulong physical, ulong flags)
|
||||
{
|
||||
size_t last_level = ((flags & MAP_HUGE_PAGE) != 0u) ? 2u : 3u;
|
||||
PageTable * pt = m_pt_base;
|
||||
for (size_t level = 0; level <= last_level; level++)
|
||||
for (size_t level = 0; level < 4u; level++)
|
||||
{
|
||||
if (level < last_level)
|
||||
if (level < 3u)
|
||||
{
|
||||
PageTableEntry entry = (*pt)[virtual, level];
|
||||
if (entry.present)
|
||||
@ -111,8 +144,7 @@ struct hurl
|
||||
}
|
||||
else
|
||||
{
|
||||
PageTable * next_pt = cast(PageTable *)hippo.allocate_page();
|
||||
memset64(next_pt, 0u, PAGE_SIZE / 8u);
|
||||
PageTable * next_pt = allocate_pt();
|
||||
(*pt)[virtual, level] = PageTableEntry(next_pt, MAP_WRITABLE | MAP_PRESENT);
|
||||
pt = next_pt;
|
||||
}
|
||||
@ -124,12 +156,23 @@ struct hurl
|
||||
}
|
||||
}
|
||||
|
||||
public static void map_range(size_t address, size_t length, ulong flags)
|
||||
public static void map_range(size_t virtual, size_t physical, size_t length, ulong flags)
|
||||
{
|
||||
size_t end = virtual + length;
|
||||
while (virtual < end)
|
||||
{
|
||||
map(virtual, physical, flags);
|
||||
virtual += PAGE_SIZE;
|
||||
physical += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
public static void identity_map_range(size_t address, size_t length, ulong flags)
|
||||
{
|
||||
size_t end = address + length;
|
||||
for (size_t page = address & ~0xFFFu; page < end; page += 0x1000u)
|
||||
for (size_t page = address & ~0xFFFu; page < end; page += PAGE_SIZE)
|
||||
{
|
||||
map(address, address, flags);
|
||||
map(page, page, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,4 +198,11 @@ struct hurl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PageTable * allocate_pt()
|
||||
{
|
||||
PageTable * pt = cast(PageTable *)hippo.allocate_page();
|
||||
memset64(pt, 0u, PAGE_SIZE / 8u);
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user