kern
changeset 7:611b2d66420b
segment descriptors
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 16 Feb 2011 07:26:03 +0200 |
parents | 7e40f14617ed |
children | 78d5c304ddd0 |
files | .gdbinit Makefile src/main.c src/segm-asm.S src/segm.c src/segm.h |
diffstat | 6 files changed, 138 insertions(+), 2 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.gdbinit Wed Feb 16 07:26:03 2011 +0200 1.3 @@ -0,0 +1,2 @@ 1.4 +file kernel.elf 1.5 +target remote localhost:1234
2.1 --- a/Makefile Thu Jan 13 20:24:10 2011 +0200 2.2 +++ b/Makefile Wed Feb 16 07:26:03 2011 +0200 2.3 @@ -1,6 +1,7 @@ 2.4 # collect all of our C and assembly source files 2.5 csrc = $(wildcard src/*.c) $(wildcard src/klibc/*.c) 2.6 asmsrc = $(wildcard src/*.S) $(wildcard src/klibc/*.S) 2.7 +dep = $(asmsrc:.S=.d) $(csrc:.c=.d) 2.8 2.9 # each source file will generate one object file 2.10 obj = $(asmsrc:.S=.o) $(csrc:.c=.o) 2.11 @@ -20,6 +21,18 @@ 2.12 $(bin): $(obj) 2.13 ld -melf_i386 -o $@ -Ttext 0x100000 -e kentry $(obj) 2.14 2.15 +-include $(dep) 2.16 + 2.17 +%.d: %.c 2.18 + @$(CPP) $(CFLAGS) -MM -MT $(@:.d=.o) $< >$@ 2.19 + 2.20 +%.d: %.S 2.21 + @$(CPP) $(ASFLAGS) -MM -MT $(@:.d=.o) $< >$@ 2.22 + 2.23 .PHONY: clean 2.24 clean: 2.25 rm -f $(obj) $(bin) 2.26 + 2.27 +.PHONY: cleandep 2.28 +cleandep: 2.29 + rm -f $(dep)
3.1 --- a/src/main.c Thu Jan 13 20:24:10 2011 +0200 3.2 +++ b/src/main.c Wed Feb 16 07:26:03 2011 +0200 3.3 @@ -2,6 +2,7 @@ 3.4 #include "vid.h" 3.5 #include "term.h" 3.6 #include <asmops.h> 3.7 +#include "segm.h" 3.8 3.9 /* special keys */ 3.10 enum { 3.11 @@ -31,12 +32,13 @@ 3.12 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 70 - 7f */ 3.13 }; 3.14 3.15 - 3.16 void kmain(void) 3.17 { 3.18 clear_scr(); 3.19 puts("kernel starting up"); 3.20 3.21 + init_segm(); 3.22 + 3.23 set_text_color(YELLOW); 3.24 puts("<initialization code goes here>"); 3.25 set_text_color(LTGRAY); 3.26 @@ -49,7 +51,7 @@ 3.27 } while(!(keypress & 1)); 3.28 inb(c, 0x60); 3.29 if(!(c & 0x80)) { 3.30 - putchar(keycodes[c]); 3.31 + putchar(keycodes[(int)c]); 3.32 } 3.33 } 3.34 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/segm-asm.S Wed Feb 16 07:26:03 2011 +0200 4.3 @@ -0,0 +1,41 @@ 4.4 + .data 4.5 +off:.long 0 4.6 +seg:.short 0 4.7 + 4.8 + .align 4.9 + .short 0 4.10 +gdt_lim: 4.11 + .short 0 4.12 +gdt_addr: 4.13 + .long 0 4.14 + 4.15 + .text 4.16 +/* setup_selectors(uint16_t code, uint16_t data) 4.17 + * loads the requested selectors to all the selector registers */ 4.18 + .globl setup_selectors 4.19 +setup_selectors: 4.20 + /* setup data selectors */ 4.21 + movl 8(%esp), %eax 4.22 + movw %ax, %ss 4.23 + movw %ax, %es 4.24 + movw %ax, %ds 4.25 + movw %ax, %gs 4.26 + movw %ax, %fs 4.27 + /* setup code selector */ 4.28 + movl 4(%esp), %eax 4.29 + movw %ax, (seg) 4.30 + movl $ldcs, (off) 4.31 + ljmp *off 4.32 +ldcs: 4.33 + ret 4.34 + 4.35 +/* set_gdt(uint32_t addr, uint16_t limit) 4.36 + * loads the GDTR with the new address and limit for the GDT */ 4.37 + .globl set_gdt 4.38 +set_gdt: 4.39 + movl 4(%esp), %eax 4.40 + movl %eax, (gdt_addr) 4.41 + movw 8(%esp), %ax 4.42 + movw %ax, (gdt_lim) 4.43 + lgdt (gdt_lim) 4.44 + ret
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/segm.c Wed Feb 16 07:26:03 2011 +0200 5.3 @@ -0,0 +1,57 @@ 5.4 +#include <string.h> 5.5 +#include "segm.h" 5.6 + 5.7 +#define BIT_ACCESSED (1 << 8) 5.8 +#define BIT_WR (1 << 9) 5.9 +#define BIT_RD (1 << 9) 5.10 +#define BIT_EXP_DOWN (1 << 10) 5.11 +#define BIT_CONFORMING (1 << 10) 5.12 +#define BIT_CODE (1 << 11) 5.13 +#define BIT_NOSYS (1 << 12) 5.14 +#define BIT_PRESENT (1 << 15) 5.15 + 5.16 +#define BIT_BIG (1 << 6) 5.17 +#define BIT_DEFAULT (1 << 6) 5.18 +#define BIT_GRAN (1 << 7) 5.19 + 5.20 +enum {TYPE_DATA, TYPE_CODE}; 5.21 + 5.22 +static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type); 5.23 + 5.24 + 5.25 +static desc_t gdt[4]; 5.26 + 5.27 + 5.28 +void init_segm(void) 5.29 +{ 5.30 + memset(gdt, 0, sizeof gdt); 5.31 + segm_desc(gdt + SEGM_KCODE, 0, 0xffffffff, 0, TYPE_CODE); 5.32 + segm_desc(gdt + SEGM_KDATA, 0, 0xffffffff, 0, TYPE_DATA); 5.33 + 5.34 + set_gdt((uint32_t)gdt, sizeof gdt - 1); 5.35 + 5.36 + setup_selectors(selector(SEGM_KCODE, 0), selector(SEGM_KDATA, 0)); 5.37 +} 5.38 + 5.39 +uint16_t selector(int idx, int rpl) 5.40 +{ 5.41 + return (idx << 3) | (rpl & 3); 5.42 +} 5.43 + 5.44 +static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type) 5.45 +{ 5.46 + desc->d[0] = limit & 0xffff; /* low order 16bits of limit */ 5.47 + desc->d[1] = base & 0xffff; /* low order 16bits of base */ 5.48 + 5.49 + /* third 16bit part contains the last 8 bits of base, the 2 priviledge 5.50 + * level bits starting on bit 13, present flag on bit 15, and type bits 5.51 + * starting from bit 8 5.52 + */ 5.53 + desc->d[2] = ((base >> 16) & 0xff) | ((dpl & 3) << 13) | BIT_PRESENT | 5.54 + BIT_NOSYS | (type == TYPE_DATA ? BIT_WR : (BIT_RD | BIT_CODE)); 5.55 + 5.56 + /* last 16bit part contains the last nibble of limit, the last byte of 5.57 + * base, and the granularity and deafult/big flags in bits 23 and 22 resp. 5.58 + */ 5.59 + desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN | BIT_BIG; 5.60 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/segm.h Wed Feb 16 07:26:03 2011 +0200 6.3 @@ -0,0 +1,21 @@ 6.4 +#ifndef SEGM_H_ 6.5 +#define SEGM_H_ 6.6 + 6.7 +#define SEGM_KCODE 1 6.8 +#define SEGM_KDATA 2 6.9 + 6.10 +typedef struct { 6.11 + uint16_t d[4]; 6.12 +} desc_t; 6.13 + 6.14 +void init_segm(void); 6.15 + 6.16 +uint16_t selector(int idx, int rpl); 6.17 + 6.18 +/* these functions are implemented in segm-asm.S */ 6.19 +void setup_selectors(uint16_t code, uint16_t data); 6.20 +void set_gdt(uint32_t addr, uint16_t limit); 6.21 + 6.22 + 6.23 + 6.24 +#endif /* SEGM_H_ */