Loading GDT in C.
This commit is contained in:
parent
879bfb0c8a
commit
a495a08cc0
@ -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")
|
||||
|
@ -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
58
src/kernel/arch/x86/gdt.c
Normal 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
26
src/kernel/arch/x86/gdt.h
Normal 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();
|
@ -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
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user