mirror of
https://github.com/kenshineto/kern.git
synced 2025-04-11 04:57:25 +00:00
Compare commits
2 commits
ff990eb0c3
...
4bf4659392
Author | SHA1 | Date | |
---|---|---|---|
4bf4659392 | |||
44694ba949 |
5 changed files with 97 additions and 35 deletions
|
@ -432,12 +432,12 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm);
|
||||||
** hierarchy. We assume that the "new" page directory exists and
|
** hierarchy. We assume that the "new" page directory exists and
|
||||||
** the system portions of it should not be touched.
|
** the system portions of it should not be touched.
|
||||||
**
|
**
|
||||||
** @param old Existing page directory
|
|
||||||
** @param new New page directory
|
** @param new New page directory
|
||||||
|
** @param old Existing page directory
|
||||||
**
|
**
|
||||||
** @return status of the duplication attempt
|
** @return status of the duplication attempt
|
||||||
*/
|
*/
|
||||||
int vm_uvmdup(pde_t *old, pde_t *new);
|
int vm_uvmdup(pde_t *new, pde_t *old);
|
||||||
|
|
||||||
#endif /* !ASM_SRC */
|
#endif /* !ASM_SRC */
|
||||||
|
|
||||||
|
|
|
@ -67,8 +67,9 @@ static void (*notify)(int);
|
||||||
|
|
||||||
// calculate the memory address of a specific character position
|
// calculate the memory address of a specific character position
|
||||||
// within VGA memory
|
// within VGA memory
|
||||||
#define VIDEO_ADDR(x, y) \
|
#define VIDEO_ADDR(x, y) \
|
||||||
(unsigned short *)(VID_BASE_ADDR + 2 * ((y) * SCREEN_X_SIZE + (x)))
|
(unsigned short *)((VID_BASE_ADDR + 2 * ((y) * SCREEN_X_SIZE + (x))) | \
|
||||||
|
0x80000000)
|
||||||
|
|
||||||
// port addresses
|
// port addresses
|
||||||
#define VGA_CTRL_IX_ADDR 0x3d4
|
#define VGA_CTRL_IX_ADDR 0x3d4
|
||||||
|
|
|
@ -431,6 +431,11 @@ static int read_phdrs(elfhdr_t *hdr, pcb_t *pcb)
|
||||||
*/
|
*/
|
||||||
static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args)
|
static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args)
|
||||||
{
|
{
|
||||||
|
#if TRACING_USER
|
||||||
|
cio_printf("stksetup: pcb %08x, entry %08, args %08x\n", (uint32_t)pcb,
|
||||||
|
entry, (uint32_t)args);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** First, we need to count the space we'll need for the argument
|
** First, we need to count the space we'll need for the argument
|
||||||
** vector and strings.
|
** vector and strings.
|
||||||
|
@ -653,7 +658,7 @@ void user_init(void)
|
||||||
|
|
||||||
// This is gross, but we need to get this information somehow.
|
// This is gross, but we need to get this information somehow.
|
||||||
// Access the "user blob" data in the second bootstrap sector
|
// Access the "user blob" data in the second bootstrap sector
|
||||||
uint16_t *blobdata = (uint16_t *)USER_BLOB_DATA;
|
uint16_t *blobdata = (uint16_t *)P2V(USER_BLOB_DATA);
|
||||||
user_offset = *blobdata++;
|
user_offset = *blobdata++;
|
||||||
user_segment = *blobdata++;
|
user_segment = *blobdata++;
|
||||||
user_sectors = *blobdata++;
|
user_sectors = *blobdata++;
|
||||||
|
@ -698,6 +703,10 @@ void user_init(void)
|
||||||
*/
|
*/
|
||||||
prog_t *user_locate(uint_t what)
|
prog_t *user_locate(uint_t what)
|
||||||
{
|
{
|
||||||
|
#if TRACING_USER
|
||||||
|
cio_printf("ulocate: %u\n", what);
|
||||||
|
#endif
|
||||||
|
|
||||||
// no programs if there is no blob!
|
// no programs if there is no blob!
|
||||||
if (user_header == NULL) {
|
if (user_header == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -733,6 +742,10 @@ prog_t *user_locate(uint_t what)
|
||||||
*/
|
*/
|
||||||
int user_duplicate(pcb_t *new, pcb_t *old)
|
int user_duplicate(pcb_t *new, pcb_t *old)
|
||||||
{
|
{
|
||||||
|
#if TRACING_USER
|
||||||
|
cio_printf("udup: old %08x new %08x\n", (uint32_t)old, (uint32_t)new);
|
||||||
|
#endif
|
||||||
|
|
||||||
// We need to do a recursive duplication of the process address
|
// We need to do a recursive duplication of the process address
|
||||||
// space of the current process. First, we create a new user
|
// space of the current process. First, we create a new user
|
||||||
// page directory. Next, we'll duplicate the USER_PDE page
|
// page directory. Next, we'll duplicate the USER_PDE page
|
||||||
|
@ -748,7 +761,7 @@ int user_duplicate(pcb_t *new, pcb_t *old)
|
||||||
|
|
||||||
// Next, add a USER_PDE page table that's a duplicate of the
|
// Next, add a USER_PDE page table that's a duplicate of the
|
||||||
// current process' page table
|
// current process' page table
|
||||||
if (!vm_uvmdup(old->pdir, new->pdir)) {
|
if (!vm_uvmdup(new->pdir, old->pdir)) {
|
||||||
// check for memory leak?
|
// check for memory leak?
|
||||||
return E_NO_MEMORY;
|
return E_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -806,6 +819,11 @@ int user_load(prog_t *ptab, pcb_t *pcb, const char **args)
|
||||||
assert1(pcb != NULL);
|
assert1(pcb != NULL);
|
||||||
assert1(args != NULL);
|
assert1(args != NULL);
|
||||||
|
|
||||||
|
#if TRACING_USER
|
||||||
|
cio_printf("uload: prog '%s' pcb %08x args %08x\n",
|
||||||
|
ptab->name[0] ? ptab->name : "?", (uint32_t)pcb, (uint32_t)args);
|
||||||
|
#endif
|
||||||
|
|
||||||
// locate the ELF binary
|
// locate the ELF binary
|
||||||
elfhdr_t *hdr = (elfhdr_t *)((uint32_t)user_header + ptab->offset);
|
elfhdr_t *hdr = (elfhdr_t *)((uint32_t)user_header + ptab->offset);
|
||||||
|
|
||||||
|
@ -864,6 +882,10 @@ int user_load(prog_t *ptab, pcb_t *pcb, const char **args)
|
||||||
*/
|
*/
|
||||||
void user_cleanup(pcb_t *pcb)
|
void user_cleanup(pcb_t *pcb)
|
||||||
{
|
{
|
||||||
|
#if TRACING_USER
|
||||||
|
cio_printf("uclean: %08x\n", (uint32_t)pcb);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pcb == NULL) {
|
if (pcb == NULL) {
|
||||||
// should this be an error?
|
// should this be an error?
|
||||||
return;
|
return;
|
||||||
|
|
91
kernel/vm.c
91
kernel/vm.c
|
@ -168,9 +168,17 @@ void vm_init(void)
|
||||||
kpdir = vm_mkkvm();
|
kpdir = vm_mkkvm();
|
||||||
assert(kpdir != NULL);
|
assert(kpdir != NULL);
|
||||||
|
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_printf("vm_init: kpdir is %08x\n", kpdir);
|
||||||
|
#endif
|
||||||
|
|
||||||
// switch to it
|
// switch to it
|
||||||
vm_set_kvm();
|
vm_set_kvm();
|
||||||
|
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_puts("vm_init: running on new kpdir\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
// install the page fault handler
|
// install the page fault handler
|
||||||
install_isr(VEC_PAGE_FAULT, vm_isr);
|
install_isr(VEC_PAGE_FAULT, vm_isr);
|
||||||
}
|
}
|
||||||
|
@ -327,9 +335,9 @@ pde_t *vm_mkkvm(void)
|
||||||
if (pdir == NULL) {
|
if (pdir == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#if TRACING_VM
|
#if 0 && TRACING_VM
|
||||||
cio_puts("\nEntering vm_mkkvm\n");
|
cio_puts( "\nEntering vm_mkkvm\n" );
|
||||||
ptdump(pdir, true, 0, N_PDE);
|
ptdump( pdir, true, 0, N_PDE );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clear it out to disable all the entries
|
// clear it out to disable all the entries
|
||||||
|
@ -351,10 +359,10 @@ pde_t *vm_mkkvm(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if TRACING_VM
|
#if 0 && TRACING_VM
|
||||||
cio_puts("\nvm_mkkvm() final PD:\n");
|
cio_puts( "\nvm_mkkvm() final PD:\n" );
|
||||||
ptdump(pdir, true, 0, 16);
|
ptdump( pdir, true, 0, 16 );
|
||||||
ptdump(pdir, true, 0x200, 16);
|
ptdump( pdir, true, 0x200, 16 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return pdir;
|
return pdir;
|
||||||
|
@ -399,7 +407,13 @@ pde_t *vm_mkuvm(void)
|
||||||
*/
|
*/
|
||||||
void vm_set_kvm(void)
|
void vm_set_kvm(void)
|
||||||
{
|
{
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_puts("Entering vm_set_kvm()\n");
|
||||||
|
#endif
|
||||||
w_cr3(V2P(kpdir)); // switch to the kernel page table
|
w_cr3(V2P(kpdir)); // switch to the kernel page table
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_puts("Exiting vm_set_kvm()\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -411,10 +425,16 @@ void vm_set_kvm(void)
|
||||||
*/
|
*/
|
||||||
void vm_set_uvm(pcb_t *p)
|
void vm_set_uvm(pcb_t *p)
|
||||||
{
|
{
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_puts("Entering vm_set_uvm()\n");
|
||||||
|
#endif
|
||||||
assert(p != NULL);
|
assert(p != NULL);
|
||||||
assert(p->pdir != NULL);
|
assert(p->pdir != NULL);
|
||||||
|
|
||||||
w_cr3(V2P(p->pdir)); // switch to process's address space
|
w_cr3(V2P(p->pdir)); // switch to process's address space
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_puts("Entering vm_set_uvm()\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -449,8 +469,8 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TRACING_VM
|
#if TRACING_VM
|
||||||
cio_printf("vm_add: pdir %08x, %s, va %08x (%u, %u pgs)\n", (uint32_t)pdir,
|
cio_printf("vm_add: pdir %08x, %s, va %08x size %u (%u pgs)\n",
|
||||||
wr ? "W" : "!W", (uint32_t)va, size);
|
(uint32_t)pdir, wr ? "W" : "!W", (uint32_t)va, size, npages);
|
||||||
cio_printf(" from %08x, %u bytes, perms %08x\n", (uint32_t)data,
|
cio_printf(" from %08x, %u bytes, perms %08x\n", (uint32_t)data,
|
||||||
bytes, entrybase);
|
bytes, entrybase);
|
||||||
#endif
|
#endif
|
||||||
|
@ -511,6 +531,10 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size,
|
||||||
*/
|
*/
|
||||||
void vm_free(pde_t *pdir)
|
void vm_free(pde_t *pdir)
|
||||||
{
|
{
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_printf("vm_free(%08x)\n", (uint32_t)pdir);
|
||||||
|
#endif
|
||||||
|
|
||||||
// do we have anything to do?
|
// do we have anything to do?
|
||||||
if (pdir == NULL) {
|
if (pdir == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -519,6 +543,8 @@ void vm_free(pde_t *pdir)
|
||||||
// iterate through the page directory entries, freeing the
|
// iterate through the page directory entries, freeing the
|
||||||
// PMTS and the frames they point to
|
// PMTS and the frames they point to
|
||||||
pde_t *curr = pdir;
|
pde_t *curr = pdir;
|
||||||
|
int nf = 0;
|
||||||
|
int nt = 0;
|
||||||
for (int i = 0; i < N_PDE; ++i) {
|
for (int i = 0; i < N_PDE; ++i) {
|
||||||
// the entry itself
|
// the entry itself
|
||||||
pde_t entry = *curr;
|
pde_t entry = *curr;
|
||||||
|
@ -537,6 +563,7 @@ void vm_free(pde_t *pdir)
|
||||||
if (IS_PRESENT(*pmt)) {
|
if (IS_PRESENT(*pmt)) {
|
||||||
// yes - free the frame
|
// yes - free the frame
|
||||||
km_page_free((void *)PTE_ADDR(*pmt));
|
km_page_free((void *)PTE_ADDR(*pmt));
|
||||||
|
++nf;
|
||||||
// mark it so we don't get surprised
|
// mark it so we don't get surprised
|
||||||
*pmt = 0;
|
*pmt = 0;
|
||||||
}
|
}
|
||||||
|
@ -545,6 +572,7 @@ void vm_free(pde_t *pdir)
|
||||||
}
|
}
|
||||||
// now, free the PMT itself
|
// now, free the PMT itself
|
||||||
km_page_free((void *)PDE_ADDR(entry));
|
km_page_free((void *)PDE_ADDR(entry));
|
||||||
|
++nt;
|
||||||
*curr = 0;
|
*curr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,6 +582,11 @@ void vm_free(pde_t *pdir)
|
||||||
|
|
||||||
// finally, free the PDIR itself
|
// finally, free the PDIR itself
|
||||||
km_page_free((void *)pdir);
|
km_page_free((void *)pdir);
|
||||||
|
++nt;
|
||||||
|
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_printf("vm_free: %d pages, %d tables\n", nf, nt);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -580,7 +613,7 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm)
|
||||||
char *last = (char *)PGDOWN(((uint32_t)va) + size - 1);
|
char *last = (char *)PGDOWN(((uint32_t)va) + size - 1);
|
||||||
|
|
||||||
#if TRACING_VM
|
#if TRACING_VM
|
||||||
cio_printf("\n\nvm_map pdir %08x va %08x pa %08x size %08x perm %03x\n",
|
cio_printf("vm_map pdir %08x va %08x pa %08x size %08x perm %03x\n",
|
||||||
(uint32_t)pdir, (uint32_t)va, pa, size, perm);
|
(uint32_t)pdir, (uint32_t)va, pa, size, perm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -591,24 +624,27 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm)
|
||||||
// couldn't find it
|
// couldn't find it
|
||||||
return E_NO_PTE;
|
return E_NO_PTE;
|
||||||
}
|
}
|
||||||
// #if TRACING_VM
|
#if 0 && TRACING_VM
|
||||||
// cio_printf( " addr %08x pa %08x last %08x pte %08x *pte %08x\n",
|
cio_printf( " addr %08x pa %08x last %08x pte %08x *pte %08x\n",
|
||||||
// (uint32_t) addr, pa, (uint32_t) last, (uint32_t) pte, *pte
|
(uint32_t) addr, pa, (uint32_t) last, (uint32_t) pte, *pte
|
||||||
// );
|
);
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
// create the new entry
|
// create the new entry for the page table
|
||||||
pde_t entry = pa | perm | PTE_P;
|
pde_t newpte = pa | perm | PTE_P;
|
||||||
|
|
||||||
// if this entry has already been mapped, we're in trouble
|
// if this entry has already been mapped, we're in trouble
|
||||||
if (IS_PRESENT(*pte)) {
|
if (IS_PRESENT(*pte)) {
|
||||||
if (*pte != entry) {
|
if (*pte != newpte) {
|
||||||
#if TRACING_VM
|
#if TRACING_VM
|
||||||
cio_puts(" ALREADY MAPPED?");
|
cio_printf(
|
||||||
cio_printf(" PDIX 0x%x PTIX 0x%x\n", PDIX(addr), PTIX(addr));
|
"vm_map: va %08x pa %08x pte %08x *pte %08x entry %08x\n",
|
||||||
|
(uint32_t)va, pa, (uint32_t)pte, (uint32_t)*pte, newpte);
|
||||||
|
cio_printf(" addr %08x PDIX 0x%x PTIX 0x%x\n", (uint32_t)addr,
|
||||||
|
PDIX(addr), PTIX(addr));
|
||||||
|
|
||||||
// dump the directory
|
// dump the directory
|
||||||
ptdump(pdir, true, 0, N_PDE);
|
ptdump(pdir, true, PDIX(addr), 4);
|
||||||
|
|
||||||
// find the relevant PDE entry
|
// find the relevant PDE entry
|
||||||
uint32_t ix = PDIX(va);
|
uint32_t ix = PDIX(va);
|
||||||
|
@ -617,16 +653,15 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm)
|
||||||
// round the PMT index down
|
// round the PMT index down
|
||||||
uint32_t ix2 = PTIX(va) & MOD4_MASK;
|
uint32_t ix2 = PTIX(va) & MOD4_MASK;
|
||||||
// dump the PMT for the relevant directory entry
|
// dump the PMT for the relevant directory entry
|
||||||
ptdump((void *)P2V(PDE_ADDR(entry)), false, ix2, 8);
|
ptdump((void *)P2V(PDE_ADDR(entry)), false, ix2, 4);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PANIC(0, "mapping an already-mapped address");
|
PANIC(0, "mapping an already-mapped address");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok, set the PTE as requested
|
// ok, set the PTE as requested
|
||||||
*pte = entry;
|
*pte = newpte;
|
||||||
|
|
||||||
// nope - move to the next page
|
// nope - move to the next page
|
||||||
addr += SZ_PAGE;
|
addr += SZ_PAGE;
|
||||||
|
@ -647,17 +682,21 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm)
|
||||||
** now have two sets of page tables that refer to the same physical
|
** now have two sets of page tables that refer to the same physical
|
||||||
** frames in memory.
|
** frames in memory.
|
||||||
**
|
**
|
||||||
** @param old Existing page directory
|
|
||||||
** @param new New page directory
|
** @param new New page directory
|
||||||
|
** @param old Existing page directory
|
||||||
**
|
**
|
||||||
** @return status of the duplication attempt
|
** @return status of the duplication attempt
|
||||||
*/
|
*/
|
||||||
int vm_uvmdup(pde_t *old, pde_t *new)
|
int vm_uvmdup(pde_t *new, pde_t *old)
|
||||||
{
|
{
|
||||||
if (old == NULL || new == NULL) {
|
if (old == NULL || new == NULL) {
|
||||||
return E_BAD_PARAM;
|
return E_BAD_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TRACING_VM
|
||||||
|
cio_printf("vmdup: old %08x new %08x\n", (uint32_t)old, (uint32_t)new);
|
||||||
|
#endif
|
||||||
|
|
||||||
// we only want to deal with the "user" half of the address space
|
// we only want to deal with the "user" half of the address space
|
||||||
for (int i = 0; i < (N_PDE >> 1); ++i) {
|
for (int i = 0; i < (N_PDE >> 1); ++i) {
|
||||||
// the entry to copy
|
// the entry to copy
|
||||||
|
|
|
@ -365,7 +365,7 @@ const pte_t id_map[N_PTE] = {
|
||||||
};
|
};
|
||||||
#endif /* MAKE_IDENTITY_MAP */
|
#endif /* MAKE_IDENTITY_MAP */
|
||||||
|
|
||||||
extern int _end;
|
extern char _end[];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Kernel address mappings, present in every page table
|
** Kernel address mappings, present in every page table
|
||||||
|
@ -375,7 +375,7 @@ const mapping_t kmap[] = {
|
||||||
{ KERN_BASE, 0, EXT_BASE, PDE_RW },
|
{ KERN_BASE, 0, EXT_BASE, PDE_RW },
|
||||||
{ KERN_VLINK, KERN_PLINK, V2P(_data), PDE_RW },
|
{ KERN_VLINK, KERN_PLINK, V2P(_data), PDE_RW },
|
||||||
// { (uint32_t) _data, V2P(_data), V2P(_end), PDE_RW },
|
// { (uint32_t) _data, V2P(_data), V2P(_end), PDE_RW },
|
||||||
{ (uint32_t)_data, V2P(_data), PHYS_TOP, PDE_RW },
|
{ (uint32_t)_data, V2P(_data), PHYS_TOP, PDE_RW }
|
||||||
{ DEV_BASE, DEV_BASE, 0, PDE_RW }
|
// { DEV_BASE, DEV_BASE, 0, PDE_RW }
|
||||||
};
|
};
|
||||||
const uint_t n_kmap = sizeof(kmap) / sizeof(kmap[0]);
|
const uint_t n_kmap = sizeof(kmap) / sizeof(kmap[0]);
|
||||||
|
|
Loading…
Add table
Reference in a new issue