Skip to content

Commit

Permalink
Initializes PIC 8259 and PIT. Re-initializes GDT. Initializes IDT. Ad…
Browse files Browse the repository at this point in the history
…ded interrupt handler. Re-factored code.
  • Loading branch information
shoily committed Jun 24, 2020
1 parent 417950d commit 791cb54
Show file tree
Hide file tree
Showing 10 changed files with 377 additions and 144 deletions.
2 changes: 1 addition & 1 deletion boot32.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

.equ KERNEL_VIRT_ADDR, 0x80000000
.equ KERNEL_PGDIR_ENTRY, (KERNEL_VIRT_ADDR >> 20)
.equ STACK_SIZE, 0x1000
.equ STACK_SIZE, 0x2000

.globl _start
_start:
Expand Down
78 changes: 75 additions & 3 deletions bootldr.S
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
.equ E820_MAP_ADDR, 0x1008
.equ PROTECTED_MODE_STACK, 0xf000
.equ KERNEL_SECTORS, ((KERNEL_SIZE + 0x200 -1) / 0x200)
.equ PIT_FREQUENCY, 1000

// machine boots in 16bit real mode
.code16
Expand All @@ -27,6 +28,65 @@
_start:
movb %dl, boot_drive

// initialize PIC

// mask master and slave PICs
movb $0xff, %al
outb %al, $0x21
outb %al, $0xa1

// init PIC1
movb $0x11, %al
outb %al, $0x20

// map vector 0x20-0x27 for IRQ 0-7
movb $0x20, %al
outb %al, $0x21

// cascade slave at IRQ 2
movb $0x4, %al
outb %al, $0x21

// Regular EOI for PIC1
movb $0x1, %al
outb %al, $0x21

// init PIC2
movb $0x11, %al
outb %al, $0xa0

// map vector 0x28-0x2f for IRQ 8-15
movb $0x28, %al
outb %al, $0xa1

// inform PIC2 that IRQ2 is the connected at PIC1
movb $0x2, %al
outb %al, $0xa1

// manual EOI for PIC2
movb $0x1, %al
outb %al, $0xa1

// small delay
movw $0xffff, %cx
1:
loop 1b

// unmask PIC1 and PIC2
xorb %al, %al
outb %al, $0x21
outb %al, $0xa1

// set PIT frequency
cli
movb $0x34, %al
outb %al, $0x43
movw PIT_FREQUENCY, %ax
outb %al, $0x40
shrw $8, %ax
outb %al, $0x40
sti

// clear screen
movb $0, %ah
movb $3, %al
Expand Down Expand Up @@ -119,8 +179,13 @@ a20_line:
xorw %ax, %ax
movw %ax, 4(%si)

// read enough sectors to load kernel
movw $KERNEL_SECTORS, %ax

// check kernel can fit into existing memory
cmpw $160, %ax
ja kernel_too_big

// read enough sectors to load kernel
movw %ax, 2(%si)

// size of the disk packet
Expand Down Expand Up @@ -166,6 +231,8 @@ a20_line:
orl $1, %eax
movl %eax, %cr0

cli

// jump to protected mode
ljmpl $0x8,$protectedmodeaddress

Expand All @@ -177,13 +244,18 @@ lba_read_error:
int $0x10
jmp loop

kernel_too_big:
// write 'B' in the screen to indicate kernel too big
movb $'X', %al
movb $0x0e, %ah
int $0x10
jmp loop

// protected mode code
.code32

protectedmodeaddress:

cli

// data descriptor is located in 0x10 location of GDT
movl $0x10, %eax
movl %eax, %ds
Expand Down
158 changes: 158 additions & 0 deletions setup32.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*****************************************************************************/
/* File: setup32.c */
/* */
/* Description: x86 32 bit GDT re-initialization code to enable IDT, LDT */
/* and TSS */
/* */
/* Author: Shoily O Rahman <[email protected]> */
/* */
/* Date: Mar 25, 2020 */
/* */
/*****************************************************************************/

#include "util.h"
#include "system.h"
#include "setup32.h"

#define UNUSED(x) (void)(x)

// GDT data
struct gdt_entry __attribute__((aligned(8))) gdt[LAST_SEG*8];

struct _gdt_desc {
unsigned short size;
struct gdt_entry *gdt;
}__attribute__((packed));

struct _gdt_desc __attribute__((aligned(8))) gdt_desc;

// IDT data
struct idt_entry __attribute__((aligned(8))) idt[256];

struct _idt_desc {
unsigned short size;
struct idt_entry *idt;
}__attribute__((packed));

struct _idt_desc __attribute__((aligned(8))) idt_desc;

void common_trap_handler();

void irq_handler_0();
void irq_handler_1();
void irq_handler_2();
void irq_handler_3();
void irq_handler_4();
void irq_handler_5();
void irq_handler_6();
void irq_handler_7();
void irq_handler_8();
void irq_handler_9();
void irq_handler_10();
void irq_handler_11();
void irq_handler_12();
void irq_handler_13();
void irq_handler_14();
void irq_handler_15();

void trap_handler() {
}


__attribute__((regparm(0))) void common_interrupt_handler(int irq) {

UNUSED(irq);
}

__attribute__((regparm(0))) void common_sys_call_handler(int syscallnr) {

UNUSED(syscallnr);
}

//
// Re-initializes GDT for kernel code and data segement selectors
//

void setupGDT32() {

// setup GDT data structure
memset(gdt, sizeof(gdt), 0);
gdt_desc.size = sizeof(gdt) - 1;
gdt_desc.gdt = gdt;

SET_KERNEL_CODE_SEGMENT(gdt, 0xfffff, 0);
SET_KERNEL_DATA_SEGMENT(gdt, 0xfffff, 0);

SET_USER_CODE_SEGMENT(gdt, 0xfffff, 0);
SET_USER_DATA_SEGMENT(gdt, 0xfffff, 0);

MFENCE;

// Re-initialize GDT
__asm__ __volatile__("movl $%0, %%eax;"
"lgdt (%%eax);"
"ljmpl %1, $reinitsegs;"
"reinitsegs:;"
"movl %2, %%eax;"
"movl %%eax, %%ds;"
"movl %%eax, %%es;"
"movl %%eax, %%ss;"
"movl %%eax, %%fs;"
"movl %%eax, %%gs;"
:
: "m" (gdt_desc), "i" (KERNEL_CODE_SEG), "i" (KERNEL_DATA_SEG)
: "%eax"
);
}

void setupIDT32() {

// setup IDT data structure
memset(idt, sizeof(idt), 0);
idt_desc.size = sizeof(idt) - 1;
idt_desc.idt = idt;


SET_TRAP_GATE(idt, 2, common_trap_handler);

SET_INTERRUPT_GATE(idt, 32, irq_handler_0);
SET_INTERRUPT_GATE(idt, 33, irq_handler_1);
SET_INTERRUPT_GATE(idt, 34, irq_handler_2);
SET_INTERRUPT_GATE(idt, 35, irq_handler_3);
SET_INTERRUPT_GATE(idt, 36, irq_handler_4);
SET_INTERRUPT_GATE(idt, 37, irq_handler_5);
SET_INTERRUPT_GATE(idt, 38, irq_handler_6);
SET_INTERRUPT_GATE(idt, 39, irq_handler_7);
SET_INTERRUPT_GATE(idt, 40, irq_handler_8);
SET_INTERRUPT_GATE(idt, 41, irq_handler_9);
SET_INTERRUPT_GATE(idt, 42, irq_handler_10);
SET_INTERRUPT_GATE(idt, 43, irq_handler_11);
SET_INTERRUPT_GATE(idt, 44, irq_handler_12);
SET_INTERRUPT_GATE(idt, 45, irq_handler_13);
SET_INTERRUPT_GATE(idt, 46, irq_handler_14);
SET_INTERRUPT_GATE(idt, 47, irq_handler_15);

MFENCE;

// Initialize IDT
__asm__ __volatile__("movl $%0, %%eax;"
"lidt (%%eax);"
"sti;"
";"
:
: "m" (idt_desc)
: "%eax"
);

}

void setup32() {

init_pic_8259();
init_pit_frequency();

setupGDT32();
setupIDT32();

print_vga("Setup GDT and IDT done", true);
}
10 changes: 5 additions & 5 deletions x86_32.h → setup32.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*****************************************************************************/
/* File: x86_32.h */
/* File: setup32.h */
/* */
/* Description: Header file for x86 32 bit data structure for GDT, IDT, TSS */
/* and related macros. */
Expand All @@ -10,8 +10,8 @@
/* */
/*****************************************************************************/

#ifndef _X86_32_H
#define _X86_32_H
#ifndef _SETUP_32_H
#define _SETUP_32_H

#define USER_CODE_SEG 0x10
#define USER_DATA_SEG 0x18
Expand Down Expand Up @@ -43,8 +43,8 @@ struct gdt_entry {
struct idt_entry {
unsigned short offset_low;
unsigned short segment_selector;
unsigned char unused;

unsigned char unused;
unsigned char type:4;
unsigned char s:1;
unsigned char dpl:2;
Expand Down Expand Up @@ -144,6 +144,6 @@ struct tss_entry {
SET_IDT_ENTRY(idt, index, 0, KERNEL_CODE_SEG, 0x5, 0, 1); \
}

void start32();
void setup32();

#endif
8 changes: 4 additions & 4 deletions start.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
/*****************************************************************************/

#include "type.h"
#include "common.h"
#include "x86.h"
#include "x86_32.h"
#include "util.h"
#include "system.h"
#include "setup32.h"

//
// Start kernel routine
Expand All @@ -24,7 +24,7 @@ int start_kernel(void) {
print_vga("XIS kernel started (v1.0)", true);
print_vga("", true);
dump_e820();
start32();
setup32();

return 0;
}
Loading

0 comments on commit 791cb54

Please sign in to comment.