diff options
| -rw-r--r-- | Makefile | 21 | ||||
| -rw-r--r-- | Makefile.common | 4 | ||||
| -rw-r--r-- | asm/GDT.asm | 3 | ||||
| -rw-r--r-- | asm/helpers.s | 43 | ||||
| -rw-r--r-- | asm/int_irq.asm | 1 | ||||
| -rw-r--r-- | asm/multiboot.s | 47 | ||||
| -rw-r--r-- | asm/usermode.s | 35 | ||||
| -rw-r--r-- | kernel/GDT.c | 136 | ||||
| -rw-r--r-- | kernel/interrupts.c | 50 | ||||
| -rw-r--r-- | kernel/kernel.c | 25 | ||||
| -rw-r--r-- | kernel/task.c | 11 | ||||
| -rw-r--r-- | kernel/usermode.c | 99 | ||||
| -rw-r--r-- | kernel/usermode.h | 1 | ||||
| -rw-r--r-- | kernel/vmem.c | 6 |
14 files changed, 375 insertions, 107 deletions
@@ -24,6 +24,7 @@ USB_STICK=/dev/sdf #use our cross compiler CC=i686-foolos-gcc +AS=i686-foolos-as ############ compiler flags ############ CFLAGS= @@ -32,7 +33,7 @@ CFLAGS= ## CFLAGS+=-w CFLAGS+=-ffreestanding CFLATS+=-Wall -CFLAGS+=-Wextra +CFLAGS+=-Wextra #CFLAGS+=-O3 #CFLAGS+=-O0 #CFLAGS+=-nostdlib @@ -50,6 +51,10 @@ LDFLAGS= LDFLAGS+=-nostdlib LDFLAGS+=-lgcc +ASFLAGS= +ASFLAGS+=-gstabs + + #verbosity #V = 0 #CC = @echo "Compiling $<..."; i686-foolos-gcc @@ -86,11 +91,12 @@ ASM_MULTIBOOT_OBJ=$(patsubst %.s, %.o, $(ASM_MULTIBOOT)) all: $(FOOLOS) tags # $(FOOLOS_VDI) new: clean all -run: run-qemu-debug +run: run-qemu +debug: run-qemu-debug newrun: clean run -########### INCLUDES ################### +########## INCLUDES ################### include Makefile.common -include $(DEPS) @@ -153,12 +159,13 @@ run-bochs: all ~/opt/bochs-2.6.6/bochs -q -f bochs/bochsrc -rc bochs/bochsdebug # run in qemu -run-qemu: all - qemu -enable-kvm $(FOOLOS) +run-qemu: + qemu -enable-kvm disk.img -s -run-qemu-debug: all +run-qemu-debug: # qemu -enable-kvm -s -S ~/temp/FoolOs/disk.img - qemu -enable-kvm -s -singlestep disk.img +# qemu -enable-kvm -s -singlestep disk.img + qemu -enable-kvm -s -S -kernel foolos.img # -initrd ext2.img stop: killall qemu diff --git a/Makefile.common b/Makefile.common index 5436c87..32bb965 100644 --- a/Makefile.common +++ b/Makefile.common @@ -5,8 +5,8 @@ %.bin: %.asm nasm -f bin $*.asm -o $@ -%.o: %.s - i686-elf-as $*.s -o $@ +#%.o: %.s +# i686-elf-as $*.s -o $@ %.o: %.c $(CC) -c $(CFLAGS) $*.c -o $*.o diff --git a/asm/GDT.asm b/asm/GDT.asm index f271377..444c313 100644 --- a/asm/GDT.asm +++ b/asm/GDT.asm @@ -15,6 +15,7 @@ ; global gdt_descriptor +global gdt_start gdt_start: @@ -76,3 +77,5 @@ CODE_SEG equ gdt_code - gdt_start DATA_SEG equ gdt_data - gdt_start CODE16_SEG equ gdt16_code - gdt_start DATA16_SEG equ gdt16_data - gdt_start + + diff --git a/asm/helpers.s b/asm/helpers.s new file mode 100644 index 0000000..6e89df6 --- /dev/null +++ b/asm/helpers.s @@ -0,0 +1,43 @@ +//http://wiki.osdev.org/GDT_Tutorial +.global setup_gdt + +// call as setup_gdt(GDT,sizeof(GDT)) +setup_gdt: + + // re-fill gdt_descriptor with new GDT location and size + movl 4(%esp),%eax + movl %eax, gdt_descriptor+2 + + movw 8(%esp),%ax + movw %ax, gdt_descriptor + // + + lgdt gdt_descriptor #load new descriptor table! + + // reload to take effect + reloadSegments: + + #Reload CS register containing code selector: + jmp $0x08,$reload_CS # 0x08 points at the new code selector + + reload_CS: + mov $0x10, %ax #0x10 points at the new data selector + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + + tss_flush: + + movb $0x2B,%ax # Load the index of our TSS structure - The index is + # 0x28, as it is the 5th selector and each is 8 bytes + # long, but we set the bottom two bits (making 0x2B) + # so that it has an RPL of 3, not zero. + ltr %ax # Load 0x2B into the task state register. + + ret + + + +ret diff --git a/asm/int_irq.asm b/asm/int_irq.asm index e9864f0..ac8eef8 100644 --- a/asm/int_irq.asm +++ b/asm/int_irq.asm @@ -127,7 +127,6 @@ int_irq13: int_irq14: cli - pop eax call exception_handle_14 ;this will never return due to panic! jmp $ diff --git a/asm/multiboot.s b/asm/multiboot.s index 1927c9b..22be3d1 100644 --- a/asm/multiboot.s +++ b/asm/multiboot.s @@ -14,6 +14,7 @@ # You don't need to understand all these details as it is just magic values that # is documented in the multiboot standard. The bootloader will search for this # magic sequence and recognize us as a multiboot kernel. + .section .multiboot .align 4 .long MAGIC @@ -49,60 +50,20 @@ stack_top: .global stack_bottom .type _start, @function _start: - # Welcome to kernel mode! We now have sufficient code for the bootloader to - # load and run our operating system. It doesn't do anything interesting yet. - # Perhaps we would like to call printf("Hello, World\n"). You should now - # realize one of the profound truths about kernel mode: There is nothing - # there unless you provide it yourself. There is no printf function. There - # is no <stdio.h> header. If you want a function, you will have to code it - # yourself. And that is one of the best things about kernel development: - # you get to make the entire system yourself. You have absolute and complete - # power over the machine, there are no security restrictions, no safe - # guards, no debugging mechanisms, there is nothing but what you build. - - # By now, you are perhaps tired of assembly language. You realize some - # things simply cannot be done in C, such as making the multiboot header in - # the right section and setting up the stack. However, you would like to - # write the operating system in a higher level language, such as C or C++. - # To that end, the next task is preparing the processor for execution of - # such code. C doesn't expect much at this point and we only need to set up - # a stack. Note that the processor is not fully initialized yet and stuff - # such as floating point instructions are not available yet. - lgdt gdt_descriptor #load descriptor table! # To set up a stack, we simply set the esp register to point to the top of # our stack (as it grows downwards). movl $stack_top, %esp - # We are now ready to actually execute C code. We cannot embed that in an - # assembly file, so we'll create a kernel.c file in a moment. In that file, - # we'll create a C entry point called kernel_main and call it here. - push %ebx #pass address of the multiboot information data structure push %eax #pass eax, so kernel can check for magic number - - - reloadSegments: - #Reload CS register containing code selector: - jmp $0x08,$reload_CS # 0x08 points at the new code selector - - reload_CS: - mov $0x10, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %ax, %ss + call kernel_main - # In case the function returns, we'll want to put the computer into an - # infinite loop. To do that, we use the clear interrupt ('cli') instruction - # to disable interrupts, the halt instruction ('hlt') to stop the CPU until - # the next interrupt arrives, and jumping to the halt instruction if it ever - # continues execution, just to be safe. We will create a local label rather - # than real symbol and jump to there endlessly. + # should never be reached + cli hlt .Lhang: diff --git a/asm/usermode.s b/asm/usermode.s new file mode 100644 index 0000000..acf4b04 --- /dev/null +++ b/asm/usermode.s @@ -0,0 +1,35 @@ +.global asm_usermode +.extern userfunc + +# pass address to func to exec (TODO) +asm_usermode: + + // 0x23 is user data segment (|2 low bits) + // 0x1b is user code segment (|2 low bits) + + // set segment registers + mov $0x23, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + // ss is handled by iret + + mov %esp, %eax + + pushl $0x23 // user data segment + pushl %eax // current stack + pushf // + + // http://x86.renejeschke.de/html/file_module_x86_id_145.html + //mov $0x200, %eax + //push %eax // eflags image + pushl $0x1B // return code segment selector + push $userfunc // return instruction pointer + iret + + jmp . // will never be reached? + + + + diff --git a/kernel/GDT.c b/kernel/GDT.c new file mode 100644 index 0000000..4bc7ca2 --- /dev/null +++ b/kernel/GDT.c @@ -0,0 +1,136 @@ +// http://wiki.osdev.org/GDT_Tutorial +#include "lib/logger/log.h" +#include "usermode.h" +#define FOOLOS_MODULE_NAME "GDT" + +#include <stdint.h> +#define GDT_SIZE 6 + +extern sys_tss; + +typedef struct GDT_struct +{ + uint32_t base; + uint32_t limit; + uint32_t type; + +}GDT; + +//alternative +struct gdt_entry_bits +{ + unsigned int limit_low:16; + unsigned int base_low : 24; + //attribute byte split into bitfields + unsigned int accessed :1; + unsigned int read_write :1; //readable for code, writable for data + unsigned int conforming_expand_down :1; //conforming for code, expand down for data + unsigned int code :1; //1 for code, 0 for data + unsigned int always_1 :1; //should be 1 for everything but TSS and LDT + unsigned int DPL :2; //priveledge level + unsigned int present :1; + //and now into granularity + unsigned int limit_high :4; + unsigned int available :1; + unsigned int always_0 :1; //should always be 0 + unsigned int big :1; //32bit opcodes for code, uint32_t stack for data + unsigned int gran :1; //1 to use 4k page addressing, 0 for byte addressing + unsigned int base_high :8; +} __packed; //or __attribute__((packed)) + + +static GDT myGDT[GDT_SIZE]; +static uint8_t gdt_struct[GDT_SIZE*8]; + +/** + * \param target A pointer to the 8-byte GDT entry + * \param source An arbitrary structure describing the GDT entry + */ +void encodeGdtEntry(uint8_t *target, GDT source) +{ + // Check the limit to make sure that it can be encoded + if ((source.limit > 65536) && (source.limit & 0xFFF) != 0xFFF) + { + panic(FOOLOS_MODULE_NAME,"trying to set an invalid GDT source.limit!"); + } + if (source.limit > 65536) { + // Adjust granularity if required + source.limit = source.limit >> 12; + target[6] = 0xC0; + } else { + target[6] = 0x40; + } + + // Encode the limit + target[0] = source.limit & 0xFF; + target[1] = (source.limit >> 8) & 0xFF; + + // Encode the base + target[2] = source.base & 0xFF; + target[3] = (source.base >> 8) & 0xFF; + target[4] = (source.base >> 16) & 0xFF; + target[7] = (source.base >> 24) & 0xFF; + + target[5] = source.type; + target[6] |= (source.limit >> 16) & 0xF; + + // And... Type + + /* + +0 1 dw 0xffff ;limit +2 3 dw 0x0 ;base +4 db 0x0 ;base +5 db 10011010b ;flags +6 db 11001111b ;flags & seg.limit +7 db 0x0 ;base + */ + + +} + +void gdt_setup() +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"setting up Global Descriptor Table"); + //selector 0x0 + myGDT[0].base=0; + myGDT[0].limit=0; + myGDT[0].type=0; + + //selector 0x8 code + myGDT[1].base=0; + myGDT[1].limit=0xffffffff; + myGDT[1].type=0x9a; + + //selector 0x10 data + myGDT[2].base=0; + myGDT[2].limit=0xffffffff; + myGDT[2].type=0x92; + + //selector 0x18 code user + myGDT[3].base=0; + myGDT[3].limit=0xffffffff; + myGDT[3].type=0xFa; + + //selector 0x20 data user + myGDT[4].base=0; + myGDT[4].limit=0xffffffff; + myGDT[4].type=0xF2; + + //TSS 0x28 + myGDT[5].base=&sys_tss; //tss start? + myGDT[5].limit=sizeof(tss_struct); //tss end? + myGDT[5].type=0x89; + + + // transcript to format the processor wants + for(int i=0;i<GDT_SIZE;i++) + encodeGdtEntry(&gdt_struct[8*i],myGDT[i]); + + + // updat + install_tss(); + setup_gdt(&gdt_struct[0],8*GDT_SIZE); + + +} diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 51d8f8e..a7e021c 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -7,6 +7,18 @@ #include "console.h" #include "x86.h" +void errlog(uint32_t error_code) +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code: 0x%08X",error_code); +} + +void deflog(uint32_t eip, uint16_t cs, uint32_t flags) +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"eip: 0x%08X",eip); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"segment: 0x%08X",cs); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"eflags: 0x%08X",flags); +} + void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr); //void mouse_handler(); @@ -36,17 +48,6 @@ void exception_handle() panic(FOOLOS_MODULE_NAME,"exception interrupt"); } -void exception_handle_14(uint32_t error_code) -{ - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code: 0x%08X",error_code); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_P: %d",error_code&1); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_W/R: %d",error_code&2); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_U/S: %d",error_code&4); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_RSVD: %d",error_code&8); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_I/D: %d",error_code&16); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"at addr: 0x%08X",x86_get_cr2()); - panic(FOOLOS_MODULE_NAME,"page fault !"); -} void int_default() { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"default handler"); @@ -76,15 +77,26 @@ void exception_handle_10(){ panic(FOOLOS_MODULE_NAME,"Invalid TSS"); } void exception_handle_11(){ panic(FOOLOS_MODULE_NAME,"Segment Not Present"); } void exception_handle_12(){ panic(FOOLOS_MODULE_NAME,"Stack Segment Overrun"); } -void exception_handle_13() +void exception_handle_13(uint32_t error_code,uint32_t eip,uint16_t cs,uint16_t unused, uint32_t flags) { - - uint32_t err; - asm("pop %eax"); // get Error Code - asm ("mov %%eax, %0":"=r"(err)); - show_error(err); + errlog(error_code); + deflog(eip,cs,flags); + + panic(FOOLOS_MODULE_NAME,"Exception: Fault: General Protection Fault"); +} - panic(FOOLOS_MODULE_NAME,"General Protection Fault"); +void exception_handle_14(uint32_t error_code,uint32_t eip,uint16_t cs,uint16_t unused, uint32_t flags) +{ + errlog(error_code); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_P: %d",error_code&1?1:0); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_W/R: %d",error_code&2?1:0); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_U/S: %d",error_code&4?1:0); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_RSVD: %d",error_code&8?1:0); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_I/D: %d",error_code&16?1:0); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"at addr: 0x%08X",x86_get_cr2()); + + deflog(eip,cs,flags); + panic(FOOLOS_MODULE_NAME,"Exception: Fault: Page Fault"); } void exception_handle_15(){ panic(FOOLOS_MODULE_NAME,"Unassigned"); } @@ -158,7 +170,7 @@ void int_init(uint16_t sel) // int_install_ir(44, 0b10001110, 0x08,&mouse_handler); //system calls - int_install_ir(0x80, 0b10001110, 0x08,&int_syscall_handler); + int_install_ir(0x80, 0b11101110, 0x08,&int_syscall_handler); int_install(); diff --git a/kernel/kernel.c b/kernel/kernel.c index 7b29730..2ce84fb 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -4,7 +4,6 @@ #error "Watchout! this is not Linux but FoolOS. Use a cross-compiler" #endif - #include "kernel.h" #include <stdint.h> @@ -18,7 +17,6 @@ #include "interrupts.h" #include "multiboot.h" - #include "console.h" #include <stddef.h> @@ -29,6 +27,7 @@ #include "video/vesa.h" #include "multiboot.h" + void kernel_main(uint32_t eax,uint32_t ebx) { @@ -37,21 +36,31 @@ void kernel_main(uint32_t eax,uint32_t ebx) // console_init(); + // // PR // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%s - compiled on %s at %s",KERNEL_VERSION,__DATE__,__TIME__); + // // Configuring the PIT timer. // timer_init(); + + // + // GDT + // + gdt_setup(); + + // // Process Multiboot Header // multiboot_information *info=get_multiboot(eax, ebx); + // // Memory Init // @@ -60,17 +69,20 @@ void kernel_main(uint32_t eax,uint32_t ebx) // uint32_t kernel_blocks=mem_init(info); + + // // Activate Virtual Memory (paging) // pdirectory *dir=vmem_init(kernel_blocks); + // // Setup Interrupts (code segment: 0x08) // - int_init(0x08); + // // Scan the PCI Bus // @@ -98,23 +110,22 @@ void kernel_main(uint32_t eax,uint32_t ebx) //smp_log_procdata(&procdata); //smp_start_aps(&procdata,0x80000); // starts at 0x80000 // but it will be copied over mbr + // // Mount Root EXT2 ramimage // - fs_mount(info); // // Initialize Multitasking // - task_init(dir); + // - // Abvoe should never return + // Abvoe should never returon // - panic(FOOLOS_MODULE_NAME,"reached end of kernel.c !!"); } diff --git a/kernel/task.c b/kernel/task.c index 1474a64..000dc74 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -82,6 +82,7 @@ volatile uint32_t my_scheduler(uint32_t oldesp) // this gets called by our clock interrupt regularly! volatile uint32_t task_switch_next(uint32_t oldesp) { + asm volatile("sti"); timer_tick(); @@ -146,12 +147,12 @@ volatile uint32_t task_fork(uint32_t oldesp) return pid; } -char *argv_init[]={"/bin/init",NULL}; -char *env_init[]={NULL}; // init task (root of all other tasks / processes) // volatile void task_init(pdirectory *dir) { + + // this is our main task on slot 0 task_list[0].parent=0; task_list[0].active=true; @@ -159,10 +160,12 @@ volatile void task_init(pdirectory *dir) task_list[0].vmem=dir; task_list[0].esp = 0; // will be set by next task_switch_next() call. current_task=0; + + + switch_to_user_mode(); - syscall_execve("/bin/init",argv_init,env_init); //syscall_execve("/bin/foolshell",argv_init,env_init); -// syscall_execve("/bin/tput",argv,env); + //syscall_execve("/bin/tput",argv,env); } diff --git a/kernel/usermode.c b/kernel/usermode.c index afad9df..339045d 100644 --- a/kernel/usermode.c +++ b/kernel/usermode.c @@ -1,32 +1,85 @@ #include "usermode.h" +#define FOOLOS_MODULE_NAME "usermode" +#include "lib/logger/log.h" +#include "syscalls.h" +tss_struct sys_tss; //Define the TSS as a global structure + + +// generic syscall interface! +int syscall(int call, int p1, int p2, int p3) +{ + int ebx; // will hold return value; + + asm("pusha"); + + // select syscall + asm("mov %0, %%eax"::"m"(call)); + + // pass params + asm("mov %0,%%edx"::"m"(p1)); + asm("mov %0,%%ecx"::"m"(p2)); + asm("mov %0,%%ebx"::"m"(p3)); + + // interrrupt + asm("int $0x80"); + + // get return value + asm("mov %%ebx, %0": "=b" (ebx)); + + asm("popa"); + + return ebx; +} +int write(int file, char *ptr, int len) +{ + return syscall(SYSCALL_WRITE,file,ptr,len); +} +int execve(char *name, char **argv, char **env) +{ + return syscall(SYSCALL_EXECVE,name,argv,env); +} + void install_tss(int cpu_no){ + // now fill each value // set values necessary - sys_tss.ss0 = 0x10; - // now set the IO bitmap (not necessary, so set above limit) - sys_tss.iomap = ( unsigned short ) sizeof( tss_struct ); + sys_tss.ss0 = 0x10; //kernel data + sys_tss.esp0 = 0x9000; //kernel stack + + // now set the IO bitmap (not necessary, so set above limit) + // sys_tss.iomap = ( unsigned short ) sizeof( tss_struct ); +} + + +void switch_to_user_mode() +{ + char text[]="internal"; + write(1,text,10); + asm_usermode(); + while(1); // will not be reached? } -void switch_to_user_mode() { - // Set up a stack structure for switching to user mode. - asm volatile(" \ - cli; \ - mov $0x23, %ax; \ - mov %ax, %ds; \ - mov %ax, %es; \ - mov %ax, %fs; \ - mov %ax, %gs; \ - \ - mov %esp, %eax; \ - pushl $0x23; \ - pushl %eax; \ - pushf; \ - mov $0x200, %eax; \ - push %eax; \ - pushl $0x1B; \ - push $1f; \ - iret; \ 1: \ - "); +char *argv_init[]={"/bin/init",NULL}; +char *env_init[]={NULL}; + +// THIS WILL BE RUN IN RING 3! +void userfunc() +{ + + execve("/bin/init",argv_init,env_init); + + for(int i=0;i<3;i++) + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"we are usermode!"); + } + + + while(1) + { + + char text[]="syscalling!"; + write(1,text,10); + } } diff --git a/kernel/usermode.h b/kernel/usermode.h index e9195e1..fafad5b 100644 --- a/kernel/usermode.h +++ b/kernel/usermode.h @@ -43,4 +43,3 @@ typedef volatile struct strtss{ unsigned short iomap; }__attribute__((packed)) tss_struct; -tss_struct sys_tss; //Define the TSS as a global structure diff --git a/kernel/vmem.c b/kernel/vmem.c index a8e4008..f49689f 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -277,6 +277,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir) pt_entry page=0; pt_entry_add_attrib (&page, I86_PTE_PRESENT); pt_entry_add_attrib (&page, I86_PTE_WRITABLE); + pt_entry_add_attrib (&page, I86_PTE_USER); pt_entry_set_frame (&page, frame); //! ...and add it to the page table @@ -287,6 +288,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir) *entry=0; pd_entry_add_attrib (entry, I86_PDE_PRESENT); pd_entry_add_attrib (entry, I86_PDE_WRITABLE); + pt_entry_add_attrib (entry, I86_PTE_USER); pd_entry_set_frame (entry, (physical_addr)table); } @@ -344,6 +346,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir) pt_entry page=0; pt_entry_add_attrib (&page, I86_PTE_PRESENT); pt_entry_add_attrib (&page, I86_PTE_WRITABLE); + pt_entry_add_attrib (&page, I86_PTE_USER); pt_entry_set_frame (&page, frame); @@ -356,6 +359,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir) *entry=0; pd_entry_add_attrib (entry, I86_PDE_PRESENT); pd_entry_add_attrib (entry, I86_PDE_WRITABLE); + pt_entry_add_attrib (entry, I86_PTE_USER); pd_entry_set_frame (entry, (physical_addr)table); virt_addr+=1024*4096; @@ -401,6 +405,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir) pt_entry page=0; pt_entry_add_attrib (&page, I86_PTE_PRESENT); pt_entry_add_attrib (&page, I86_PTE_WRITABLE); + pt_entry_add_attrib (&page, I86_PTE_USER); pt_entry_set_frame (&page, frame); @@ -413,6 +418,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir) *entry=0; pd_entry_add_attrib (entry, I86_PDE_PRESENT); pd_entry_add_attrib (entry, I86_PDE_WRITABLE); + pt_entry_add_attrib (entry, I86_PTE_USER); pd_entry_set_frame (entry, (physical_addr)table); virt_addr+=1024*4096; |
