Skip to content

Commit

Permalink
Added support for user mode page allocation. Uses it in usermode prog…
Browse files Browse the repository at this point in the history
…ram for text section and stack. PGD changes can be at local CPU GDT using MAP_LOCAL_CPU flag. Added support for unmapping pages. Uses separate locks for kernel and usermode GDT entries. Prints debugging information on usermode page fault.
  • Loading branch information
shoily committed Feb 20, 2022
1 parent 2af9af9 commit de6097f
Show file tree
Hide file tree
Showing 16 changed files with 440 additions and 123 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ld -static -T kernel32.ld -m elf_i386 -nostdlib --nmagic boot32.o util.o system.

objdump -x xiskernel.elf | grep _end_kernel_initial_pg_table | awk -Wposix '{cmd="printf %d 0x" $1; cmd | getline decimal; close(cmd); if (decimal > 4294963200) print "STOP: Not enough memory to map pagetables. Upgrade to 64bit kernel.";}'<br>
objcopy -O binary xiskernel.elf xiskernel.bin<br>
echo ".equ KERNEL_SIZE, `ls -l xiskernel.bin | cut -f5 -d\ `" > krnlsize.S<br>
echo ".equ KERNEL_SIZE, &#96;ls -l xiskernel.bin | cut -f5 -d\ &#96;" > krnlsize.S<br>
awk '/KERNEL_SIZE/{var=$3; cmd="objdump -x xiskernel.elf | grep INITIAL_KMAPPED_MEMORY | cut -f1 -d\\ "; cmd | getline hex;close(cmd); cmd="printf %d 0x" hex; cmd | getline decimal; if ((var-4096) > decimal) printf("STOP: Map atleast 0x%x bytes in boot32.S. Currently mapped 0x%x bytes", var, decimal);}' krnlsize.S<br>

<b>Instructions for building boot loader -</b><br>
Expand Down
22 changes: 11 additions & 11 deletions acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ void acpi_process_madt(ACPI_TABLE *madt) {

remaining_bytes -= apic_table->length;

//printf(KERNEL_INFO, "Type: %d, L: %d ", (int)apic_table->type, (int)apic_table->length);
//printf(KERNEL_INFO, "Type: %d, L: %d ", (int)apic_table->type, (int)apic_table->length);

switch(apic_table->type) {

Expand All @@ -150,14 +150,14 @@ void acpi_process_madt(ACPI_TABLE *madt) {
} break;
case 1:
{
printf(KERNEL_INFO, "IOAPIC_ID: %d, Addr: %x, GSIBase: %d", (int)apic_table->info.ioapic.id, (int)apic_table->info.ioapic.address, (int)apic_table->info.ioapic.gsi_base);
printf(KERNEL_INFO, "IOAPIC_ID: %d, Addr: %x, GSIBase: %d ", (int)apic_table->info.ioapic.id, (int)apic_table->info.ioapic.address, (int)apic_table->info.ioapic.gsi_base);
ioapic_allocate(apic_table->info.ioapic.id,
(u32)apic_table->info.ioapic.address,
(int)apic_table->info.ioapic.gsi_base);
} break;
case 2:
{
printf(KERNEL_INFO, "Bus: %d, Src: %d, GSI: %d, Flags: %d", (int)apic_table->info.int_src_override.bus, (int)apic_table->info.int_src_override.source, (int)apic_table->info.int_src_override.gsi, (int)apic_table->info.int_src_override.flags);
printf(KERNEL_INFO, "Bus: %d, Src: %d, GSI: %d, Flags: %d ", (int)apic_table->info.int_src_override.bus, (int)apic_table->info.int_src_override.source, (int)apic_table->info.int_src_override.gsi, (int)apic_table->info.int_src_override.flags);

interrupt_set_override(apic_table->info.int_src_override.bus,
apic_table->info.int_src_override.source,
Expand All @@ -167,11 +167,11 @@ void acpi_process_madt(ACPI_TABLE *madt) {
} break;
case 3:
{
printf(KERNEL_INFO, "Flags: %x GSI: %d", (int)apic_table->info.nmi_source.flags, (int)apic_table->info.nmi_source.gsi);
printf(KERNEL_INFO, "Flags: %x GSI: %d ", (int)apic_table->info.nmi_source.flags, (int)apic_table->info.nmi_source.gsi);
} break;
case 4:
{
printf(KERNEL_INFO, "UID: %d, lint: %d, flags: %d", (int)apic_table->info.lapic_nmi.uid, (int)apic_table->info.lapic_nmi.lapic_lint, (int)apic_table->info.lapic_nmi.flags);
printf(KERNEL_INFO, "UID: %d, lint: %d, flags: %d ", (int)apic_table->info.lapic_nmi.uid, (int)apic_table->info.lapic_nmi.lapic_lint, (int)apic_table->info.lapic_nmi.flags);
} break;

}
Expand All @@ -181,10 +181,9 @@ void acpi_process_madt(ACPI_TABLE *madt) {
}

void acpi_process_table(ACPI_TABLE *acpi_table) {

char sig[5];

map_kernel_linear_with_pagetable((addr_t)acpi_table, acpi_table->length, PTE_PRESENT);
map_kernel_linear_with_pagetable((addr_t)acpi_table, acpi_table->length, PTE_PRESENT, false);
for(int i=0;i<4;i++)
sig[i] = acpi_table->signature[i];
sig[4] = 0;
Expand All @@ -208,15 +207,16 @@ void acpi_init() {
}

rsdt = (ACPI_TABLE*)ADDPTRS(rsdp->rsdt_address, KERNEL_VIRT_ADDR);
map_kernel_linear_with_pagetable((addr_t)rsdt, sizeof(ACPI_TABLE), PTE_PRESENT);
map_kernel_linear_with_pagetable((addr_t)rsdt, rsdt->length, PTE_PRESENT);
printf(KERNEL_INFO, "RSDT: %p\n", (long)rsdt-KERNEL_VIRT_ADDR);
printf(KERNEL_INFO, "RSDT Length: %d, %d\n", rsdt->length, sizeof(ACPI_TABLE));
map_kernel_linear_with_pagetable((addr_t)rsdt, sizeof(ACPI_TABLE), PTE_PRESENT, MAP_LOCAL_CPU);
map_kernel_linear_with_pagetable((addr_t)rsdt, rsdt->length, PTE_PRESENT, MAP_LOCAL_CPU);
printf(KERNEL_INFO, "RSDT: %p ", (long)rsdt-KERNEL_VIRT_ADDR);
printf(KERNEL_INFO, "RSDT Length: %d, %d ", rsdt->length, sizeof(ACPI_TABLE));

num_acpi_tables = (rsdt->length - sizeof(ACPI_TABLE)) / sizeof(void*);
acpi_tables = (ACPI_TABLE**)ADDPTRS(rsdt, sizeof(ACPI_TABLE));

for(int i=0;i<num_acpi_tables;i++) {
acpi_process_table((ACPI_TABLE*)ADDPTRS(acpi_tables[i], KERNEL_VIRT_ADDR));
}
printf(KERNEL_INFO, "\n");
}
25 changes: 12 additions & 13 deletions apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
#include "setup32.h"
#include "debug.h"

int lapic_present;
int lapic_present = 0;
int lapic_base_register;
int lapic_id;

extern addr_t _kernel_pg_dir;

char __attribute__((aligned(4096))) lapic_pg_table[4096];
// char __attribute__((aligned(4096))) lapic_pg_table[4096];

void read_msr(int msr, int *eax, int *edx) {

Expand Down Expand Up @@ -65,36 +65,35 @@ void calibrate_lapic_timer() {
void init_lapic() {

int eax, edx;
pte_t *pgtable[1];

lapic_present = 0;
int local_lapic_present = 0;

__asm__ __volatile__("movl $1, %%eax;"
"cpuid;"
"andl $0x200, %%edx;"
"shrl $9, %%edx;"
"movl %%edx, %0;"
: "=r" (lapic_present)
: "=r" (local_lapic_present)
:
: "%eax", "%edx"
);

printf(KERNEL_INFO, "Local APIC present: %d\n", lapic_present);

if (!lapic_present) {
printf(KERNEL_INFO, "Local APIC present: %d ", local_lapic_present);

if (!local_lapic_present) {
return;
}

memset(lapic_pg_table, 0, sizeof(lapic_pg_table));
pgtable[0] = (pte_t*)lapic_pg_table;
// memset(lapic_pg_table, 0, sizeof(lapic_pg_table));
// pgtable[0] = (pte_t*)lapic_pg_table;

read_msr(0x1b, &eax, &edx);
lapic_base_register = eax & 0xfffff000;

build_pagetable(0, pgtable, lapic_base_register, lapic_base_register, PAGE_SIZE, PGD_PRESENT | PGD_WRITE, PTE_PRESENT | PTE_WRITE);
map_kernel_with_pagetable(lapic_base_register, lapic_base_register, PAGE_SIZE, PTE_WRITE, MAP_LOCAL_CPU);

lapic_present = local_lapic_present;

printf(KERNEL_INFO, "Local APIC address: %p\n", eax);
printf(KERNEL_INFO, "Local APIC address: %p ", eax);

lapic_id = lapic_read_register(LAPIC_ID_REG) >> 24;

Expand Down
4 changes: 3 additions & 1 deletion lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
/* Author: Shoily O Rahman <[email protected]> */
/* */
/* Date: Oct 16, 2020 */
/* Lock order - spinlock_smp->lock_pgd */
/* Lock order - */
/* spinlock_smp->lock_pgd (kernel) */
/* lock_pgd (user)->spinlock_page_alloc */
/* */
/*****************************************************************************/

Expand Down
38 changes: 10 additions & 28 deletions memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "memory.h"
#include "system.h"
#include "util.h"
#include "lock.h"
#include "page32.h"
#include "smp.h"

Expand Down Expand Up @@ -54,20 +53,6 @@ struct cache_desc {
// bitmap
};

struct kpage {
// CONVERT_64
u8 npages;
u8 flags;
u32 refcount;
void *virt_addr;
spinlock lock;
union {
struct cache_desc *desc; // for actual cache page
u32 free_slot_count; // for cache metadata
struct list adjacent_pages;
};
};

struct cache_fixed {
u32 size;
u32 chunk_size;
Expand All @@ -84,10 +69,6 @@ enum KPAGE_ALLOC_MODE {
#define CACHE_MIN_CHUNK_SIZE (int)sizeof(long)
#define CACHE_MAX_NUM 10

#define ERR_NOMEM -1
#define ERR_SUCCESS 0
#define ERR_RETRY 1

spinlock spinlock_page_alloc;
struct mem_cache cache[CACHE_MAX_NUM] = {0};

Expand Down Expand Up @@ -151,15 +132,15 @@ s32 mem_init() {
}

if (nr_pgtbls)
map_kernel_linear_with_pagetable(ADDPTRS(KERNEL_VIRT_ADDR, INITIAL_KMAPPED_MEMORY), nr_pgtbls << PAGE_SHIFT, PTE_PRESENT | PTE_WRITE);
map_kernel_linear_with_pagetable(ADDPTRS(KERNEL_VIRT_ADDR, INITIAL_KMAPPED_MEMORY), nr_pgtbls << PAGE_SHIFT, PTE_PRESENT | PTE_WRITE, false);

if (ADDPTRS(end_kernel_pgtbls, kpages_memory) > ADDPTRS(KERNEL_VIRT_ADDR, INITIAL_KMAPPED_MEMORY)) {
if ((addr_t)kpages < ADDPTRS(KERNEL_VIRT_ADDR, INITIAL_KMAPPED_MEMORY))
if ((addr_t)kpages < (addr_t)ADDPTRS(KERNEL_VIRT_ADDR, INITIAL_KMAPPED_MEMORY))
kpage_beyond_mapping = ADDPTRS(KERNEL_VIRT_ADDR, INITIAL_KMAPPED_MEMORY);
else
kpage_beyond_mapping = (addr_t)kpages;

map_kernel_linear_with_pagetable(kpage_beyond_mapping, kpages_memory, PTE_PRESENT | PTE_WRITE);
map_kernel_linear_with_pagetable(kpage_beyond_mapping, kpages_memory, PTE_PRESENT | PTE_WRITE, false);
}

end_kernel_data = ADDPTRS(kpages, kpages_memory);
Expand Down Expand Up @@ -213,12 +194,12 @@ s32 mem_init() {
kpages[BASE_WRITE_PAGE >> PAGE_SHIFT].flags &= ~KPAGE_FLAGS_FREE;
kpages[BASE_WRITE_PAGE >> PAGE_SHIFT].flags |= (KPAGE_FLAGS_ALLOCATED | KPAGE_FLAGS_NOT_FREEABLE);

map_kernel_linear_with_pagetable(ADDPTRS(KERNEL_VIRT_ADDR, BASE_WRITE_PAGE), PAGE_SIZE, PTE_PRESENT | PTE_WRITE);
map_kernel_linear_with_pagetable(ADDPTRS(KERNEL_VIRT_ADDR, BASE_WRITE_PAGE), PAGE_SIZE, PTE_PRESENT | PTE_WRITE, false);

for(mp_addr = AP_INIT_PHYS_TEXT & PAGE_MASK; mp_addr < ALIGN_PAGE(AP_INIT_PHYS_TEXT + init_ap_size); mp_addr += PAGE_SIZE) {
kpages[mp_addr >> PAGE_SHIFT].flags &= ~KPAGE_FLAGS_FREE;
kpages[mp_addr >> PAGE_SHIFT].flags |= (KPAGE_FLAGS_ALLOCATED | KPAGE_FLAGS_NOT_FREEABLE);
map_kernel_linear_with_pagetable(mp_addr, PAGE_SIZE, PTE_PRESENT | PTE_WRITE);
map_kernel_linear_with_pagetable(mp_addr, PAGE_SIZE, PTE_PRESENT | PTE_WRITE, false);
}

kpage_last = kpage-1;
Expand Down Expand Up @@ -501,9 +482,6 @@ void *mem_cache_allocate(int size) {
return (void*)ADDPTRS(page, first_bit * cache->size);
}

//void page_free_pages(struct kpage *kpage) {
//}

void mem_cache_free(void *ptr) {
struct kpage *kpage;

Expand Down Expand Up @@ -535,7 +513,11 @@ void *page_alloc_kmap_linear(u32 npages) {
return NULL;

addr = ADDPTRS((page-kpages) << PAGE_SHIFT, KERNEL_VIRT_ADDR);
map_kernel_linear_with_pagetable(addr, npages << PAGE_SHIFT, PTE_PRESENT | PTE_WRITE);
map_kernel_linear_with_pagetable(addr, npages << PAGE_SHIFT, PTE_PRESENT | PTE_WRITE, false);
memset(addr, 0, PAGE_SIZE * npages);
return (void*)addr;
}

void page_free(void *addr) {
(void*)addr++;
}
26 changes: 26 additions & 0 deletions memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define MEMORY_H

#include "type.h"
#include "lock.h"

#define KPAGE_FLAGS_FREE 1
#define KPAGE_FLAGS_ALLOCATED 2
Expand All @@ -25,8 +26,33 @@

#define KPAGE_FLAGS_MASK 0xffffffff

#define ERR_NOMEM -1
#define ERR_INVALID -2
#define ERR_NOT_SUPPORTED -3
#define ERR_SUCCESS 0
#define ERR_RETRY 1

#define KPAGE_TO_PHYS_ADDR(page) (((page) - kpages) << PAGE_SHIFT)

struct kpage {
// CONVERT_64
u8 npages;
u8 flags;
u32 refcount;
void *virt_addr;
spinlock lock;
union {
struct cache_desc *desc; // for actual cache page
u32 free_slot_count; // for cache metadata
struct list adjacent_pages;
};
};

extern struct kpage *kpages;

s32 mem_init();
struct kpage *page_alloc(u32 npages);
void *page_alloc_kmap_linear(u32 npages);
void page_free(void *addr);

#endif
Loading

0 comments on commit de6097f

Please sign in to comment.