From Godmar Back, with changes.
{
uint32_t *pd, *pt;
size_t page;
+ extern char _start, _end_kernel_text;
pd = base_page_dir = palloc_get_page (PAL_ASSERT | PAL_ZERO);
pt = NULL;
for (page = 0; page < ram_pages; page++)
{
uintptr_t paddr = page * PGSIZE;
- void *vaddr = ptov (paddr);
+ char *vaddr = ptov (paddr);
size_t pde_idx = pd_no (vaddr);
size_t pte_idx = pt_no (vaddr);
+ bool in_kernel_text = &_start <= vaddr && vaddr < &_end_kernel_text;
if (pd[pde_idx] == 0)
{
pd[pde_idx] = pde_create (pt);
}
- pt[pte_idx] = pte_create_kernel (vaddr, true);
+ pt[pte_idx] = pte_create_kernel (vaddr, !in_kernel_text);
}
/* Store the physical address of the page directory into CR3
/* Kernel starts with code, followed by read-only data and writable data. */
.text : { *(.start) *(.text) } = 0x90
- .rodata : { *(.rodata) *(.rodata.*) }
+ .rodata : { *(.rodata) *(.rodata.*) . = ALIGN(0x1000); }
+ _end_kernel_text = .;
.data : { *(.data) }
/* BSS (zero-initialized data) is after everything else. */
The PTE's page is readable.
If WRITABLE is true then it will be writable as well.
The page will be usable only by ring 0 code (the kernel). */
-static inline uint32_t pte_create_kernel (uint32_t *page, bool writable) {
+static inline uint32_t pte_create_kernel (void *page, bool writable) {
ASSERT (pg_ofs (page) == 0);
return vtop (page) | PTE_P | (writable ? PTE_W : 0);
}
The PTE's page is readable.
If WRITABLE is true then it will be writable as well.
The page will be usable by both user and kernel code. */
-static inline uint32_t pte_create_user (uint32_t *page, bool writable) {
+static inline uint32_t pte_create_user (void *page, bool writable) {
return pte_create_kernel (page, writable) | PTE_U;
}