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)
|
public static void initialize(ulong acpi_xsdt_phys)
|
||||||
{
|
{
|
||||||
/* Map the XSDT header. */
|
/* 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;
|
const(Xsdt) * xsdt = cast(const(Xsdt) *)acpi_xsdt_phys;
|
||||||
if (xsdt.header.signature != XSDT_SIGNATURE)
|
if (xsdt.header.signature != XSDT_SIGNATURE)
|
||||||
{
|
{
|
||||||
@ -66,12 +66,12 @@ struct acpi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Map the entire XSDT. */
|
/* 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;
|
size_t n_entries = (xsdt.header.length - xsdt.header.sizeof) / xsdt.tables[0].sizeof;
|
||||||
for (size_t i = 0u; i < n_entries; i++)
|
for (size_t i = 0u; i < n_entries; i++)
|
||||||
{
|
{
|
||||||
ulong address = xsdt.tables[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;
|
uint signature = *cast(const(uint) *)address;
|
||||||
if (signature == APIC_SIGNATURE)
|
if (signature == APIC_SIGNATURE)
|
||||||
{
|
{
|
||||||
@ -83,7 +83,7 @@ struct acpi
|
|||||||
private static parse_apic_table(ulong address)
|
private static parse_apic_table(ulong address)
|
||||||
{
|
{
|
||||||
const(MadtHeader) * madt_header = cast(const(MadtHeader) *)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;
|
apic_address = madt_header.local_apic_address;
|
||||||
klog.writefln("Found 32-bit APIC address: 0x%x", apic_address);
|
klog.writefln("Found 32-bit APIC address: 0x%x", apic_address);
|
||||||
const(void) * madt_end = cast(const(void) *)(address + madt_header.length);
|
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;
|
private static __gshared size_t n_free_pages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Physical address limit.
|
||||||
|
*/
|
||||||
|
public static __gshared size_t physical_address_limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize HIPPO.
|
* Initialize HIPPO.
|
||||||
*
|
*
|
||||||
@ -54,7 +59,7 @@ struct hippo
|
|||||||
[header.bootinfo.hulk_phys, cast(ulong)header.total_size - LinkerAddresses.hulk_bss_size],
|
[header.bootinfo.hulk_phys, cast(ulong)header.total_size - LinkerAddresses.hulk_bss_size],
|
||||||
[header.bootinfo.bss_phys, LinkerAddresses.hulk_bss_size],
|
[header.bootinfo.bss_phys, LinkerAddresses.hulk_bss_size],
|
||||||
[header.bootinfo.stack_phys, header.stack_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],
|
[header.bootinfo.pt_phys, header.bootinfo.pt_size],
|
||||||
];
|
];
|
||||||
for (size_t ri = 0u; ri < reserved.length; ri++)
|
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 = header.bootinfo.memory_map[bii].base;
|
||||||
ulong phys_end = phys + header.bootinfo.memory_map[bii].size;
|
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;
|
usable_memory += header.bootinfo.memory_map[bii].size;
|
||||||
while (phys < phys_end)
|
while (phys < phys_end)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,6 @@ void hulk_start()
|
|||||||
cli();
|
cli();
|
||||||
gdt.initialize();
|
gdt.initialize();
|
||||||
idt.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);
|
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.initialize();
|
||||||
console.clear();
|
console.clear();
|
||||||
@ -50,6 +49,7 @@ void hulk_start()
|
|||||||
klog.writefln("Welcome to HULK, the HOS UltraLight Kernel!");
|
klog.writefln("Welcome to HULK, the HOS UltraLight Kernel!");
|
||||||
|
|
||||||
hippo.initialize(&hulk_header);
|
hippo.initialize(&hulk_header);
|
||||||
|
hurl.initialize(&hulk_header);
|
||||||
pci.initialize();
|
pci.initialize();
|
||||||
pic.initialize();
|
pic.initialize();
|
||||||
acpi.initialize(hulk_header.bootinfo.acpi_xsdt_phys);
|
acpi.initialize(hulk_header.bootinfo.acpi_xsdt_phys);
|
||||||
|
@ -9,6 +9,8 @@ import hos.cpu;
|
|||||||
import hulk.hippo;
|
import hulk.hippo;
|
||||||
import hos.memory;
|
import hos.memory;
|
||||||
import hulk.klog;
|
import hulk.klog;
|
||||||
|
import hulk.header;
|
||||||
|
import hulk.linker_addresses;
|
||||||
|
|
||||||
/** HULK virtual base address. */
|
/** HULK virtual base address. */
|
||||||
enum ulong HULK_VIRTUAL_BASE_ADDRESS = 0xFFFF_8000_0000_0000u;
|
enum ulong HULK_VIRTUAL_BASE_ADDRESS = 0xFFFF_8000_0000_0000u;
|
||||||
@ -91,18 +93,49 @@ struct hurl
|
|||||||
|
|
||||||
private static __gshared PageTable * m_pt_base;
|
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)
|
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;
|
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];
|
PageTableEntry entry = (*pt)[virtual, level];
|
||||||
if (entry.present)
|
if (entry.present)
|
||||||
@ -111,8 +144,7 @@ struct hurl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PageTable * next_pt = cast(PageTable *)hippo.allocate_page();
|
PageTable * next_pt = allocate_pt();
|
||||||
memset64(next_pt, 0u, PAGE_SIZE / 8u);
|
|
||||||
(*pt)[virtual, level] = PageTableEntry(next_pt, MAP_WRITABLE | MAP_PRESENT);
|
(*pt)[virtual, level] = PageTableEntry(next_pt, MAP_WRITABLE | MAP_PRESENT);
|
||||||
pt = next_pt;
|
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;
|
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