Merge pull request #1 from Azomasiel/gdt
Memory management: Global Descriptor Table
This commit is contained in:
		
						commit
						439394c667
					
				
							
								
								
									
										1
									
								
								.bochsrc
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								.bochsrc
									
									
									
									
									
								
							@ -11,6 +11,7 @@ clock: sync=realtime
 | 
				
			|||||||
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
 | 
					ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
 | 
				
			||||||
ata0-master: type=cdrom, path="k.iso", status=inserted
 | 
					ata0-master: type=cdrom, path="k.iso", status=inserted
 | 
				
			||||||
boot: cdrom
 | 
					boot: cdrom
 | 
				
			||||||
 | 
					magic_break: enabled=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# write serial logs to stdout
 | 
					# write serial logs to stdout
 | 
				
			||||||
com1: enabled=1, mode=file, dev=/dev/stdout
 | 
					com1: enabled=1, mode=file, dev=/dev/stdout
 | 
				
			||||||
 | 
				
			|||||||
@ -30,7 +30,8 @@ OBJS	= \
 | 
				
			|||||||
	  libvga.o \
 | 
						  libvga.o \
 | 
				
			||||||
	  list.o \
 | 
						  list.o \
 | 
				
			||||||
	  memory.o \
 | 
						  memory.o \
 | 
				
			||||||
	  serial.o
 | 
						  serial.o \
 | 
				
			||||||
 | 
						  gdt.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEPS = $(OBJS:.o=.d)
 | 
					DEPS = $(OBJS:.o=.d)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										122
									
								
								k/gdt.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										122
									
								
								k/gdt.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,122 @@
 | 
				
			|||||||
 | 
					#include "gdt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct gdt gdt = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void create_kernel_ds()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct gdt_entry *entry = gdt.entries + KERNEL_DS_INDEX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t limit = 0xfffff;
 | 
				
			||||||
 | 
					    uint32_t base = 0x0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->granularity = 1;
 | 
				
			||||||
 | 
					    entry->db = 1;
 | 
				
			||||||
 | 
					    entry->l = 0;
 | 
				
			||||||
 | 
					    entry->available = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->present = 1;
 | 
				
			||||||
 | 
					    entry->desc_priv = 0;
 | 
				
			||||||
 | 
					    entry->desc_type = 1;
 | 
				
			||||||
 | 
					    entry->ex = 0;
 | 
				
			||||||
 | 
					    entry->dc = 0;
 | 
				
			||||||
 | 
					    entry->rw = 1;
 | 
				
			||||||
 | 
					    entry->accessed = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->limit_1 = limit & 0xffff;
 | 
				
			||||||
 | 
					    entry->limit_2 = (limit >> 16) & 0xf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->base_1 = base & 0xffff;
 | 
				
			||||||
 | 
					    entry->base_2 = (base >> 16) & 0xff;
 | 
				
			||||||
 | 
					    entry->base_3 = (base >> 24) & 0xff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void create_kernel_cs()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct gdt_entry *entry = gdt.entries + KERNEL_CS_INDEX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t limit = 0xfffff;
 | 
				
			||||||
 | 
					    uint32_t base = 0x0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->granularity = 1;
 | 
				
			||||||
 | 
					    entry->db = 1;
 | 
				
			||||||
 | 
					    entry->l = 0;
 | 
				
			||||||
 | 
					    entry->available = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->present = 1;
 | 
				
			||||||
 | 
					    entry->desc_priv = 0;
 | 
				
			||||||
 | 
					    entry->desc_type = 1;
 | 
				
			||||||
 | 
					    entry->ex = 1;
 | 
				
			||||||
 | 
					    entry->dc = 0;
 | 
				
			||||||
 | 
					    entry->rw = 1;
 | 
				
			||||||
 | 
					    entry->accessed = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->limit_1 = limit & 0xffff;
 | 
				
			||||||
 | 
					    entry->limit_2 = (limit >> 16) & 0xf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    entry->base_1 = base & 0xffff;
 | 
				
			||||||
 | 
					    entry->base_2 = (base >> 16) & 0xff;
 | 
				
			||||||
 | 
					    entry->base_3 = (base >> 24) & 0xff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void create_gdt()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    create_kernel_ds();
 | 
				
			||||||
 | 
					    create_kernel_cs();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void load_gdt()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct gdt_r gdtr;
 | 
				
			||||||
 | 
					    gdtr.addr = (uint32_t)&gdt;
 | 
				
			||||||
 | 
					    gdtr.limit = GDT_SIZE - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    asm volatile("lgdt %0\n"
 | 
				
			||||||
 | 
					            :
 | 
				
			||||||
 | 
					            : "m" (gdtr)
 | 
				
			||||||
 | 
					            : "memory");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void load_ds()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct segment_selector selector;
 | 
				
			||||||
 | 
					    selector.index = KERNEL_DS_INDEX;
 | 
				
			||||||
 | 
					    selector.table_indicator = 0;
 | 
				
			||||||
 | 
					    selector.rpl = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    asm volatile("movw %0, %%ax\n"
 | 
				
			||||||
 | 
					                 "movw %%ax, %%ds\n"
 | 
				
			||||||
 | 
					                 "movw %%ax, %%fs\n"
 | 
				
			||||||
 | 
					                 "movw %%ax, %%gs\n"
 | 
				
			||||||
 | 
					                 "movw %%ax, %%ss\n"
 | 
				
			||||||
 | 
					            :
 | 
				
			||||||
 | 
					            : "m" (selector)
 | 
				
			||||||
 | 
					            : "ax");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void load_cs()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct segment_selector selector;
 | 
				
			||||||
 | 
					    selector.index = KERNEL_CS_INDEX;
 | 
				
			||||||
 | 
					    selector.table_indicator = 0;
 | 
				
			||||||
 | 
					    selector.rpl = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    asm volatile("pushl %0\n"
 | 
				
			||||||
 | 
					                 "pushl $1f\n"
 | 
				
			||||||
 | 
					                 "lret\n"
 | 
				
			||||||
 | 
					                 "1:\n"
 | 
				
			||||||
 | 
					             :
 | 
				
			||||||
 | 
					             : "m" (selector));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void reload_segment_selectors()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    load_ds();
 | 
				
			||||||
 | 
					    load_cs();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void init_gdt()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    create_gdt();
 | 
				
			||||||
 | 
					    load_gdt();
 | 
				
			||||||
 | 
					    reload_segment_selectors();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										52
									
								
								k/gdt.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										52
									
								
								k/gdt.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					#ifndef GDT_H
 | 
				
			||||||
 | 
					#define GDT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GDT_NB_ENTRIES 3
 | 
				
			||||||
 | 
					#define GDT_SIZE (GDT_NB_ENTRIES * sizeof(struct gdt_entry))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define KERNEL_CS_INDEX 1
 | 
				
			||||||
 | 
					#define KERNEL_DS_INDEX 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gdt_entry
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint16_t limit_1    : 16;
 | 
				
			||||||
 | 
					    uint16_t base_1     : 16;
 | 
				
			||||||
 | 
					    uint8_t base_2      : 8;
 | 
				
			||||||
 | 
					    uint8_t accessed    : 1;
 | 
				
			||||||
 | 
					    uint8_t rw          : 1;
 | 
				
			||||||
 | 
					    uint8_t dc          : 1;
 | 
				
			||||||
 | 
					    uint8_t ex          : 1;
 | 
				
			||||||
 | 
					    uint8_t desc_type   : 1;
 | 
				
			||||||
 | 
					    uint8_t desc_priv   : 2;
 | 
				
			||||||
 | 
					    uint8_t present     : 1;
 | 
				
			||||||
 | 
					    uint8_t limit_2     : 4;
 | 
				
			||||||
 | 
					    uint8_t available   : 1;
 | 
				
			||||||
 | 
					    uint8_t l           : 1;
 | 
				
			||||||
 | 
					    uint8_t db          : 1;
 | 
				
			||||||
 | 
					    uint8_t granularity : 1;
 | 
				
			||||||
 | 
					    uint8_t base_3      : 8;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gdt
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct gdt_entry entries[GDT_NB_ENTRIES];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct gdt_r
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint16_t limit;
 | 
				
			||||||
 | 
					    uint32_t addr;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct segment_selector
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t rpl             : 2;
 | 
				
			||||||
 | 
					    uint8_t table_indicator : 1;
 | 
				
			||||||
 | 
					    uint16_t index          : 13;
 | 
				
			||||||
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void init_gdt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* !GDT_H */
 | 
				
			||||||
							
								
								
									
										1
									
								
								k/k.c
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								k/k.c
									
									
									
									
									
								
							@ -30,6 +30,7 @@
 | 
				
			|||||||
static void k_init(void)
 | 
					static void k_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    init_serial();
 | 
					    init_serial();
 | 
				
			||||||
 | 
					    init_gdt();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void k_main(unsigned long magic, multiboot_info_t *info)
 | 
					void k_main(unsigned long magic, multiboot_info_t *info)
 | 
				
			||||||
 | 
				
			|||||||
@ -24,12 +24,12 @@ void init_serial(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int write(const char *buf, size_t count)
 | 
					int write(const char *buf, size_t count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int sent;
 | 
					    size_t sent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(sent = 0; sent < count; ++sent)
 | 
					    for(sent = 0; sent < count; ++sent)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        u8 line_status = inb(COM1 + 5);
 | 
					        u8 line_status = inb(COM1 + 5);
 | 
				
			||||||
        if (!line_status & EMPTY_TRANSMITTER)
 | 
					        if (!(line_status & EMPTY_TRANSMITTER))
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        outb(COM1, buf[sent]);
 | 
					        outb(COM1, buf[sent]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user