it wont work goddammit
This commit is contained in:
parent
12193e7920
commit
35d08c3a9c
6
Makefile
6
Makefile
|
@ -37,11 +37,11 @@ obj/%.o: src/%.asm
|
|||
|
||||
|
||||
run: clean bin/shade.iso
|
||||
qemu-system-x86_64 -hdd bin/shade.iso
|
||||
qemu-system-x86_64 -hdd bin/shade.iso -d int -no-reboot
|
||||
|
||||
debug: clean bin/shade.iso bin/shade.bin
|
||||
qemu-system-x86_64 -s -S -hdd bin/shade.iso &
|
||||
${GDB} os-image.bin -ex "symbol-file bin/shade.bin" -ex "target remote localhost:1234"
|
||||
qemu-system-x86_64 -s -S -hdd bin/shade.iso -d int -no-reboot &
|
||||
${GDB} os-image.bin -ex "set arch i386:x86-64" -ex "symbol-file bin/shade.bin" -ex "target remote localhost:1234"
|
||||
|
||||
|
||||
clean:
|
||||
|
|
BIN
bin/shade.bin
BIN
bin/shade.bin
Binary file not shown.
BIN
bin/shade.iso
BIN
bin/shade.iso
Binary file not shown.
|
@ -0,0 +1,57 @@
|
|||
# configuration file generated by Bochs
|
||||
plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, iodebug=true, pcidev=false, usb_uhci=false
|
||||
config_interface: textconfig
|
||||
display_library: x
|
||||
memory: host=32, guest=32
|
||||
romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x00000000, options=none
|
||||
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest"
|
||||
boot: floppy
|
||||
floppy_bootsig_check: disabled=0
|
||||
floppya: type=1_44
|
||||
# no floppyb
|
||||
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
||||
ata0-master: type=disk, path="bin/shade.iso", mode=flat, cylinders=0, heads=0, spt=0, sect_size=512, model="Generic 1234", biosdetect=auto, translation=auto
|
||||
ata0-slave: type=none
|
||||
ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15
|
||||
ata1-master: type=none
|
||||
ata1-slave: type=none
|
||||
ata2: enabled=false
|
||||
ata3: enabled=false
|
||||
optromimage1: file=none
|
||||
optromimage2: file=none
|
||||
optromimage3: file=none
|
||||
optromimage4: file=none
|
||||
optramimage1: file=none
|
||||
optramimage2: file=none
|
||||
optramimage3: file=none
|
||||
optramimage4: file=none
|
||||
pci: enabled=1, chipset=i440fx, slot1=none, slot2=none, slot3=none, slot4=none, slot5=none
|
||||
vga: extension=vbe, update_freq=5, realtime=1, ddc=builtin
|
||||
cpu: count=1:1:1, ips=4000000, quantum=16, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="AuthenticAMD", brand_string="AMD Athlon(tm) processor"
|
||||
cpuid: mmx=true, apic=xapic, simd=sse2, sse4a=false, misaligned_sse=false, sep=true
|
||||
cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, avx_f16c=false
|
||||
cpuid: avx_fma=false, bmi=0, xop=false, fma4=false, tbm=false, x86_64=true, 1g_pages=false
|
||||
cpuid: pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true
|
||||
print_timestamps: enabled=0
|
||||
debugger_log: -
|
||||
magic_break: enabled=0
|
||||
port_e9_hack: enabled=0
|
||||
private_colormap: enabled=0
|
||||
clock: sync=none, time0=local, rtc_sync=0
|
||||
# no cmosimage
|
||||
log: -
|
||||
logprefix: %t%e%d
|
||||
debug: action=ignore
|
||||
info: action=report
|
||||
error: action=report
|
||||
panic: action=ask
|
||||
keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
|
||||
mouse: type=ps2, enabled=false, toggle=ctrl+mbutton
|
||||
speaker: enabled=true, mode=system
|
||||
parport1: enabled=true, file=none
|
||||
parport2: enabled=false
|
||||
com1: enabled=true, mode=null
|
||||
com2: enabled=false
|
||||
com3: enabled=false
|
||||
com4: enabled=false
|
BIN
obj/boot.o
BIN
obj/boot.o
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,4 @@
|
|||
|
||||
gdt_start: ; use labels to compute sizes and jumps
|
||||
; gdt starts with 8 byte null
|
||||
dd 0x0
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef GDT_H
|
||||
#define GDT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// the GDT descriptor format makes literally no sense, who came up with this
|
||||
typedef struct {
|
||||
uint16_t limit_low16; // Low 16 bits of limit
|
||||
uint16_t base_low16; // Low 16 bits of base
|
||||
uint8_t base_mid8; // Middle 8 bits of base
|
||||
uint8_t access; // 7: present, 6-5: priv level, 4: type, 3: executable, 2: dc, 1: rw, 0: accessed (zero)
|
||||
uint8_t limit_flags; // High 4 bits of limit AND flags (?? why). flags: 3: granularity, 2: size, 1: long, 0: reserved
|
||||
uint8_t base_high8; // High 8 bits of base
|
||||
} __attribute__((packed)) gdt_entry_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t size; // GDT size (bytes) - 1
|
||||
uint32_t offset; // Address of element 0 of the GDT
|
||||
} __attribute__((packed)) gdt_ptr_t;
|
||||
|
||||
static gdt_entry_t gdt[8192];
|
||||
static gdt_ptr_t gdtr;
|
||||
|
||||
void init_gdt();
|
||||
void gdt_set_segment(int limit, int base, int access);
|
||||
void load_gdt();
|
||||
|
||||
#endif
|
14
src/boot.asm
14
src/boot.asm
|
@ -18,6 +18,8 @@ stack_bottom:
|
|||
resb 16384
|
||||
stack_top:
|
||||
|
||||
%include "src/gdt.asm"
|
||||
|
||||
; _start = entry to kernel
|
||||
; Since the bootloader will be gone, it doesn't make sense to return from this
|
||||
section .text
|
||||
|
@ -27,6 +29,18 @@ _start:
|
|||
; 32bit protected mode, no int, no paging
|
||||
mov esp, stack_top ; Initialize stack
|
||||
|
||||
cli ; Disable interrupts
|
||||
lgdt [gdt_descriptor] ; load the GDT
|
||||
jmp CODE_SEG:.reload_seg ; far jump into a different segment
|
||||
|
||||
.reload_seg: ; now in 32bit
|
||||
mov ax, DATA_SEG ; update segment registers
|
||||
mov ds, ax
|
||||
mov ss, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
extern kmain
|
||||
call kmain
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
section .data
|
||||
|
||||
gdt_start: ; use labels to compute sizes and jumps
|
||||
; gdt starts with 8 byte null
|
||||
dd 0x0
|
||||
dd 0x0
|
||||
|
||||
; GDT for code segment, base = 0x00000000, length = 0xfffff
|
||||
gdt_code:
|
||||
dw 0xffff ; segment length
|
||||
dw 0x0 ; segment base
|
||||
db 0x0 ; segment base
|
||||
db 10011010b ; flags
|
||||
db 11001111b ; flags + segment length
|
||||
db 0x0 ; segment base
|
||||
|
||||
; GDT for data segment
|
||||
gdt_data:
|
||||
dw 0xffff ; segment length
|
||||
dw 0x0 ; segment base
|
||||
db 0x0 ; segment base
|
||||
db 10010010b ; flags
|
||||
db 11001111b ; flags + segment length
|
||||
db 0x0 ; segment base
|
||||
|
||||
gdt_end:
|
||||
|
||||
gdt_descriptor:
|
||||
dw gdt_end - gdt_start - 1 ; size, always 1 less than what it actually is
|
||||
dd gdt_start ; address
|
||||
|
||||
CODE_SEG equ gdt_code - gdt_start
|
||||
DATA_SEG equ gdt_data - gdt_start
|
|
@ -1,3 +1,6 @@
|
|||
set timeout=0
|
||||
set default=0
|
||||
|
||||
menuentry "shadeOS Dev Build" {
|
||||
multiboot /boot/shade.bin
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
#include "./platform/drivers/ports.h"
|
||||
#include "print.h"
|
||||
#include "./platform/types.h"
|
||||
//#include "./platform/interrupts/int.h"
|
||||
#include "./platform/interrupts/int.h"
|
||||
|
||||
void dummy_test_entrypoint() {}
|
||||
|
||||
|
@ -46,10 +45,10 @@ void kmain() {
|
|||
print_str("Copyright (c) e3team 2022. All rights reserved.\n");
|
||||
print_str("This program is provided \"as-is\" and no express or implied warranty is provided.\n");
|
||||
print_str("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n");
|
||||
/*
|
||||
|
||||
idt_init();
|
||||
kernel_msg_ok("Interrupts initialized");
|
||||
|
||||
__asm__ __volatile__("int $2");
|
||||
*/
|
||||
|
||||
//kernel_msg_ok("Interrupts working");
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include "int.h"
|
||||
#include "../../print.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int count = 0;
|
||||
|
||||
void exception_handler() {
|
||||
print_str("I");
|
||||
}
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) {
|
||||
idt_entry_t* descriptor = &idt[vector];
|
||||
|
||||
descriptor->isr_low = (uint32_t)isr & 0xFFFF;
|
||||
descriptor->kernel_cs = 0x08; // this value can be whatever offset your kernel code selector is in your GDT
|
||||
descriptor->attributes = flags;
|
||||
descriptor->isr_high = (uint32_t)isr >> 16;
|
||||
descriptor->reserved = 0;
|
||||
}
|
||||
|
||||
void idt_init() {
|
||||
idtr.base = (uint32_t)&idt[0];
|
||||
idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1;
|
||||
|
||||
for (uint8_t vector = 0; vector < 32; vector++) {
|
||||
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
||||
isr_stub_table[vector] = true;
|
||||
}
|
||||
|
||||
__asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT
|
||||
__asm__ volatile ("sti"); // set the interrupt flag
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef INT_H
|
||||
#define INT_H
|
||||
|
||||
#include "../../util.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||
uint8_t reserved; // Set to zero
|
||||
uint8_t attributes; // Type and attributes; see the IDT page
|
||||
uint16_t isr_high; // The higher 16 bits of the ISR's address
|
||||
} __attribute__((packed)) idt_entry_t;
|
||||
|
||||
__attribute__((aligned(0x10)))
|
||||
static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance
|
||||
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint32_t base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
|
||||
static idtr_t idtr;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ds; /* Data segment selector */
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
|
||||
uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */
|
||||
uint32_t eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */
|
||||
} registers_t;
|
||||
|
||||
__attribute__((noreturn))
|
||||
void exception_handler();
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||
|
||||
extern void* isr_stub_table[];
|
||||
|
||||
void idt_init(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,101 @@
|
|||
%macro isr_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
;push byte %1 ; Push interrupt no to stack
|
||||
|
||||
; 1. Save CPU state
|
||||
;pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
|
||||
;mov ax, ds ; Lower 16-bits of eax = ds.
|
||||
;push eax ; save the data segment descriptor
|
||||
;mov ax, 0x10 ; kernel data segment descriptor
|
||||
;mov ds, ax
|
||||
;mov es, ax
|
||||
;mov fs, ax
|
||||
;mov gs, ax
|
||||
|
||||
; 2. Call C handler
|
||||
call exception_handler
|
||||
|
||||
; 3. Restore state
|
||||
;pop eax
|
||||
;mov ds, ax
|
||||
;mov es, ax
|
||||
;mov fs, ax
|
||||
;mov gs, ax
|
||||
;popa
|
||||
;add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||
%endmacro
|
||||
; if writing for 64-bit, use iretq instead
|
||||
%macro isr_no_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
;push byte 0 ; No error occured
|
||||
;push byte %1 ; Push interrupt no to stack
|
||||
|
||||
; 1. Save CPU state
|
||||
;pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
|
||||
;mov ax, ds ; Lower 16-bits of eax = ds.
|
||||
;push eax ; save the data segment descriptor
|
||||
;mov ax, 0x10 ; kernel data segment descriptor
|
||||
;mov ds, ax
|
||||
;mov es, ax
|
||||
;mov fs, ax
|
||||
;mov gs, ax
|
||||
|
||||
; 2. Call C handler
|
||||
call exception_handler
|
||||
|
||||
; 3. Restore state
|
||||
;pop eax
|
||||
;mov ds, ax
|
||||
;mov es, ax
|
||||
;mov fs, ax
|
||||
;mov gs, ax
|
||||
;popa
|
||||
;add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
||||
;sti
|
||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||
%endmacro
|
||||
|
||||
extern exception_handler
|
||||
|
||||
isr_no_err_stub 0
|
||||
isr_no_err_stub 1
|
||||
isr_no_err_stub 2
|
||||
isr_no_err_stub 3
|
||||
isr_no_err_stub 4
|
||||
isr_no_err_stub 5
|
||||
isr_no_err_stub 6
|
||||
isr_no_err_stub 7
|
||||
isr_err_stub 8
|
||||
isr_no_err_stub 9
|
||||
isr_err_stub 10
|
||||
isr_err_stub 11
|
||||
isr_err_stub 12
|
||||
isr_err_stub 13
|
||||
isr_err_stub 14
|
||||
isr_no_err_stub 15
|
||||
isr_no_err_stub 16
|
||||
isr_err_stub 17
|
||||
isr_no_err_stub 18
|
||||
isr_no_err_stub 19
|
||||
isr_no_err_stub 20
|
||||
isr_no_err_stub 21
|
||||
isr_no_err_stub 22
|
||||
isr_no_err_stub 23
|
||||
isr_no_err_stub 24
|
||||
isr_no_err_stub 25
|
||||
isr_no_err_stub 26
|
||||
isr_no_err_stub 27
|
||||
isr_no_err_stub 28
|
||||
isr_no_err_stub 29
|
||||
isr_err_stub 30
|
||||
isr_no_err_stub 31
|
||||
|
||||
global isr_stub_table
|
||||
isr_stub_table:
|
||||
%assign i 0
|
||||
%rep 32
|
||||
dd isr_stub_%+i ; use DQ instead if targeting 64-bit
|
||||
%assign i i+1
|
||||
%endrep
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
typedef unsigned int u32;
|
||||
typedef int i32;
|
||||
typedef unsigned short u16;
|
||||
typedef short i16;
|
||||
typedef unsigned char u8;
|
||||
typedef char i8;
|
||||
|
||||
#define high16(i32) (i32 & 0xffff)
|
||||
#define low16(i32) ((i32>>16) & 0xffff)
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define NULL 0
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
#include "strings.h"
|
||||
#include "./platform/types.h"
|
||||
#include <stddef.h>
|
||||
|
||||
void itoa(int n, char str[]) {
|
||||
int i, sign;
|
||||
|
|
Loading…
Reference in New Issue