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_ */