kern

changeset 49:50730d42d2d3

fuck yeah, now do priviledge levels and TSS
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 30 Jul 2011 07:21:54 +0300
parents 4c9c16754b59
children 1d8877d12de0
files src/intr-asm.S src/intr.h src/proc.c src/vm.c
diffstat 4 files changed, 57 insertions(+), 13 deletions(-) [+]
line diff
     1.1 --- a/src/intr-asm.S	Thu Jul 28 17:56:05 2011 +0300
     1.2 +++ b/src/intr-asm.S	Sat Jul 30 07:21:54 2011 +0300
     1.3 @@ -70,9 +70,15 @@
     1.4  intr_entry_common:
     1.5  	pusha
     1.6  	call dispatch_intr
     1.7 +	jmp 0f
     1.8  
     1.9  	.globl intr_ret
    1.10  intr_ret:
    1.11 +	/* if called as a function from context_switch, we must
    1.12 +	 * remove the pushed return address before continuing
    1.13 +     */
    1.14 +	add $4, %esp
    1.15 +0:	/* ... we skip to here otherwise */
    1.16  	popa
    1.17  	/* remove error code and intr num from stack */
    1.18  	add $8, %esp
     2.1 --- a/src/intr.h	Thu Jul 28 17:56:05 2011 +0300
     2.2 +++ b/src/intr.h	Sat Jul 30 07:21:54 2011 +0300
     2.3 @@ -24,7 +24,7 @@
     2.4  	uint32_t eip, cs, eflags;
     2.5  	/* pushed by CPU during interrupt entry from user space */
     2.6  	uint32_t esp, ss;
     2.7 -};
     2.8 +} __attribute__ ((packed));
     2.9  
    2.10  
    2.11  
     3.1 --- a/src/proc.c	Thu Jul 28 17:56:05 2011 +0300
     3.2 +++ b/src/proc.c	Sat Jul 30 07:21:54 2011 +0300
     3.3 @@ -26,12 +26,13 @@
     3.4  	 * and copy the code of test_proc there.
     3.5  	 * (should be mapped at a fixed address)
     3.6  	 */
     3.7 -	proc_size_pg = (test_proc_end - test_proc) / PGSIZE + 1;
     3.8 +	/*proc_size_pg = (test_proc_end - test_proc) / PGSIZE + 1;
     3.9  	if((img_start_pg = pgalloc(proc_size_pg, MEM_USER)) == -1) {
    3.10  		panic("failed to allocate space for the init process image\n");
    3.11  	}
    3.12  	img_start = (void*)PAGE_TO_ADDR(img_start_pg);
    3.13 -	memcpy(img_start, test_proc, proc_size_pg * PGSIZE);
    3.14 +	memcpy(img_start, test_proc, proc_size_pg * PGSIZE);*/
    3.15 +	img_start = test_proc;
    3.16  
    3.17  	/* instruction pointer at the beginning of the process image */
    3.18  	proc[0].ctx.instr_ptr = (uint32_t)img_start;
    3.19 @@ -47,8 +48,8 @@
    3.20  	proc[0].ctx.pgtbl_paddr = clone_vm();
    3.21  
    3.22  	/* we don't need the image and the stack in this address space */
    3.23 -	unmap_page_range(img_start_pg, proc_size_pg);
    3.24 -	pgfree(img_start_pg, proc_size_pg);
    3.25 +	/*unmap_page_range(img_start_pg, proc_size_pg);
    3.26 +	pgfree(img_start_pg, proc_size_pg);*/
    3.27  
    3.28  	unmap_page(stack_pg);
    3.29  	pgfree(stack_pg, 1);
    3.30 @@ -69,6 +70,7 @@
    3.31  	struct intr_frame ifrm;
    3.32  	struct context *ctx = &proc[pid].ctx;
    3.33  
    3.34 +
    3.35  	cur_pid = pid;
    3.36  
    3.37  	ifrm.inum = ifrm.err = 0;
    3.38 @@ -76,10 +78,19 @@
    3.39  	ifrm.regs = ctx->regs;
    3.40  	ifrm.eflags = ctx->flags;
    3.41  
    3.42 +	ifrm.err = 0xbadf00d;
    3.43 +
    3.44 +	asm volatile (
    3.45 +		"pushf\n\t"
    3.46 +		"popl %0\n\t"
    3.47 +		: "=a" (ifrm.eflags)
    3.48 +	);
    3.49 +
    3.50  	ifrm.eip = ctx->instr_ptr;
    3.51 -	ifrm.cs = SEGM_KCODE;	/* XXX change this when we setup the TSS */
    3.52 -	ifrm.esp = ctx->stack_ptr;
    3.53 -	ifrm.ss = SEGM_KDATA;	/* XXX */
    3.54 +	ifrm.cs = selector(SEGM_KCODE, 0);	/* XXX change this when we setup the TSS */
    3.55 +	ifrm.esp = 0;/*ctx->stack_ptr;			/* this will only be used when we switch to userspace */
    3.56 +	ifrm.regs.esp = ctx->stack_ptr;		/* ... until then... */
    3.57 +	ifrm.ss = 0;/*selector(SEGM_KDATA, 0);	/* XXX */
    3.58  
    3.59  	/* switch to the vm of the process */
    3.60  	set_pgdir_addr(ctx->pgtbl_paddr);
     4.1 --- a/src/vm.c	Thu Jul 28 17:56:05 2011 +0300
     4.2 +++ b/src/vm.c	Sat Jul 30 07:21:54 2011 +0300
     4.3 @@ -328,8 +328,35 @@
     4.4  	node = pglist[area];
     4.5  	while(node) {
     4.6  		if(start >= node->start && start + num <= node->end) {
     4.7 -			ret = node->start;
     4.8 -			node->start += num;
     4.9 +			ret = start;	/* can do .. */
    4.10 +
    4.11 +			if(start == node->start) {
    4.12 +				/* adjacent to the start of the range */
    4.13 +				node->start += num;
    4.14 +			} else if(start + num == node->end) {
    4.15 +				/* adjacent to the end of the range */
    4.16 +				node->end = start;
    4.17 +			} else {
    4.18 +				/* somewhere in the middle, which means we need
    4.19 +				 * to allocate a new page_range
    4.20 +				 */
    4.21 +				struct page_range *newnode;
    4.22 +
    4.23 +				if(!(newnode = alloc_node())) {
    4.24 +					panic("pgalloc_vrange failed to allocate new page_range while splitting a range in half... bummer\n");
    4.25 +				}
    4.26 +				newnode->start = start + num;
    4.27 +				newnode->end = node->end;
    4.28 +				newnode->next = node->next;
    4.29 +
    4.30 +				node->end = start;
    4.31 +				node->next = newnode;
    4.32 +				/* no need to check for null nodes at this point, there's
    4.33 +				 * certainly stuff at the begining and the end, otherwise we
    4.34 +				 * wouldn't be here. so break out of it.
    4.35 +				 */
    4.36 +				break;
    4.37 +			}
    4.38  
    4.39  			if(node->start == node->end) {
    4.40  				prev->next = node->next;
    4.41 @@ -526,7 +553,7 @@
    4.42  	/* we will allocate physical pages and map them to this virtual page
    4.43  	 * as needed in the loop below.
    4.44  	 */
    4.45 -	free_phys_page(virt_to_phys(tblpg));
    4.46 +	free_phys_page(virt_to_phys((uint32_t)ntbl));
    4.47  
    4.48  	kstart_dirent = ADDR_TO_PAGE(KMEM_START) / 1024;
    4.49  
    4.50 @@ -548,10 +575,10 @@
    4.51  
    4.52  	/* kernel space */
    4.53  	for(i=kstart_dirent; i<1024; i++) {
    4.54 -		ndir[i] = *PGTBL(i);
    4.55 +		ndir[i] = pgdir[i];
    4.56  	}
    4.57  
    4.58 -	paddr = virt_to_phys(dirpg);
    4.59 +	paddr = virt_to_phys((uint32_t)ndir);
    4.60  
    4.61  	/* unmap before freeing to avoid deallocating the physical pages */
    4.62  	unmap_page(dirpg);