Loading GDT in C.

This commit is contained in:
Nicolás Ortega Froysa 2018-04-04 17:50:29 +02:00
parent 879bfb0c8a
commit a495a08cc0
No known key found for this signature in database
GPG Key ID: FEC70E3BAE2E69BF
6 changed files with 117 additions and 68 deletions

View File

@ -47,6 +47,8 @@ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "i.86")
set(SRCS
src/kernel/arch/x86/boot.s
${SRCS}
src/kernel/arch/x86/gdt.s
src/kernel/arch/x86/gdt.c
src/kernel/arch/x86/tty.c)
set(CMAKE_EXE_LINKER_FLAGS
"-T ${CMAKE_CURRENT_SOURCE_DIR}/src/kernel/arch/x86/linker.ld -ffreestanding -nostdlib")

View File

@ -45,8 +45,8 @@ stack_bottom:
.skip 16384 # 16 KiB
stack_top:
.section .data
.include "gdt.s"
/*.section .data
.include "gdt.s"*/
/*
* The linker script specifies the `_start' label as the entry point to the kernel
@ -59,19 +59,10 @@ stack_top:
_start:
# set the position of `%esp' to the top of the stack
mov $stack_top, %esp
mov %esp, %ebp
# GDT, paging, and other features
flush_gdt:
cli
lgdt (gdtr)
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $0x08, $flush_end
flush_end:
call gdt_install
boot_kernel:
# enter high-level kernel (C)

58
src/kernel/arch/x86/gdt.c Normal file
View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gdt.h"
/*
* ENTRIES:
* 0 - NULL entry
* 1/2 - kernel entries
* 3/4 - user entries
* 5 - TSS entry
*/
#define GDT_SIZE 3
struct segdesc gdt[GDT_SIZE];
struct segreg gdtr;
void gdt_entry_set(struct segdesc *entry, uint32_t base,
uint32_t limit, uint8_t access, uint8_t gran) {
// base
entry->base_low = base & 0xFFFF;
entry->base_mid = (base >> 16) & 0xFF;
entry->base_high = (base >> 24) & 0xFF;
// limit
entry->limit_low = limit & 0xFFFF;
entry->gran = (limit >> 16) & 0x0F;
// access and granularity flags
entry->gran |= gran & 0xF0;
entry->access = access;
}
void gdt_install() {
gdtr.base = (uint32_t)gdt;
gdtr.limit = sizeof(gdt)-1;
gdt_entry_set(&gdt[0], 0, 0, 0, 0);
gdt_entry_set(&gdt[1], 0, 0xFFFFFFFF, 0x9A, 0xCF);
gdt_entry_set(&gdt[2], 0, 0xFFFFFFFF, 0x92, 0xCF);
gdt_flush(&gdtr);
}

26
src/kernel/arch/x86/gdt.h Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "structs.h"
extern void gdt_flush(struct segreg *gdtr);
void gdt_entry_set(struct segdesc *entry, uint32_t base,
uint32_t limit, uint8_t access, uint8_t gran);
void gdt_install();

View File

@ -16,57 +16,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Create the GDT
*/
gdt_start:
gdt_null:
.long 0x0
.long 0x0
gdt_kcode:
.word 0xFFFF # limit
.word 0x0 # base
.byte 0x0 # base
.byte 0b10011010 # 1st flags | type flags
.byte 0b11001111 # 2nd flags | limit
.byte 0x0 # base
gdt_kdata:
.word 0xFFFF # limit
.word 0x0 # base
.byte 0x0 # base
.byte 0b10010010 # 1st flags | type flags
.byte 0b11001111 # 2nd flags | limit
.byte 0x0 # base
gdt_ucode:
.word 0xFFFF # limit
.word 0x0 # base
.byte 0x0 # base
.byte 0b11111010 # 1st flags | type flags
.byte 0b11001111 # 2nd flags | limit
.byte 0x0 # base
gdt_udata:
.word 0xFFFF # limit
.word 0x0 # base
.byte 0x0 # base
.byte 0b11110010 # 1st flags | type flags
.byte 0b11001111 # 2nd flags | limit
.byte 0x0 # base
# TODO: setup the TSS
gdt_tss:
.word 0x0 # size of TSS (set later)
.word 0x0 # address of TSS (set later)
.byte 0x0 # address of TSS (set later)
.byte 0b10010001 # 1st flags | type flags
.byte 0b01000000 # 2nd flags | size of TSS (set later
.byte 0x0 # address of TSS (set later)
gdt_end:
gdtr:
.word (gdt_end - gdt_start - 1)
.long gdt_start
.section .text
.global gdt_flush
.type gdt_flush, @function
gdt_flush:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
cli
lgdt (%eax)
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ljmp $0x0008, $gdt_flush_end
gdt_flush_end:
popl %ebp
ret

View File

@ -18,10 +18,12 @@
#pragma once
#include <stdint.h>
struct segdesc {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t base_mid;
uint8_t access;
uint8_t gran;
uint8_t base_high;
@ -72,3 +74,8 @@ struct tss {
uint16_t iopb_r; // reserved
uint16_t iopb;
} __attribute__((packed));
struct segreg {
uint16_t limit;
uint32_t base;
} __attribute__((packed));