Merge branch 'feature/rewrite'
This commit is contained in:
commit
a6f98cddb6
84 changed files with 860 additions and 114 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,2 +1,2 @@
|
||||||
i386-elf-toolchain-aur
|
bin/
|
||||||
i386-elf-tools-aur-pkgs
|
obj/
|
83
Makefile
83
Makefile
|
@ -1,56 +1,67 @@
|
||||||
# $@ = target file
|
ASM := nasm
|
||||||
# $< = first dependency
|
|
||||||
# $^ = all dependencies
|
|
||||||
|
|
||||||
GDB = gdb
|
CC := x86_64-elf-gcc
|
||||||
|
CCFLAGS :=
|
||||||
|
|
||||||
C_FILES = $(shell find src/ -type f -name '*.c')
|
LD := x86_64-elf-ld
|
||||||
CO_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES))
|
LDFLAGS :=
|
||||||
ASM_FILES = $(shell find src/kernel/ -type f -name '*.asm')
|
|
||||||
AO_FILES = $(patsubst src/kernel/%.asm, obj/kernel/%.o, $(ASM_FILES))
|
|
||||||
ABIN_FILES = $(patsubst src/%.asm, bin/%.bin, $(ASM_FILES))
|
|
||||||
|
|
||||||
os-image.bin: bin/boot.bin bin/kernel.bin
|
INCLUDE := include/
|
||||||
cat $^ > $@
|
|
||||||
|
|
||||||
bin/boot.bin: src/boot/boot.asm bin/kernel.bin .FORCE
|
# Target: kernel, type: C ASM
|
||||||
sed -i.orig "s@CH_REPLACE_BOOTSECTORCOUNT@$(shell ./getinblocks.py $(shell du -b "bin/kernel.bin" | cut -f 1))@g" src/boot/kernel.asm
|
kernel_c_source_files = $(shell find src/kernel/ -type f -name *.c)
|
||||||
nasm -Isrc/boot/ $< -f bin -o $@
|
kernel_c_object_files = $(patsubst src/%.c,obj/%.o,$(kernel_c_source_files))
|
||||||
mv src/boot/kernel.asm.orig src/boot/kernel.asm
|
kernel_asm_source_files = $(shell find src/kernel/ -type f -name *.asm)
|
||||||
|
kernel_asm_object_files = $(patsubst src/%.asm,obj/%.o,$(kernel_asm_source_files))
|
||||||
|
kernel_source_files = $(kernel_c_source_files) $(kernel_asm_object_files)
|
||||||
|
kernel_object_files = $(kernel_c_object_files) $(kernel_asm_object_files)
|
||||||
|
|
||||||
.FORCE:
|
# Target: libc, type: C ASM
|
||||||
|
libc_c_source_files = $(shell find src/libc/ -type f -name *.c)
|
||||||
|
libc_c_object_files = $(patsubst src/%.c,obj/%.o,$(libc_c_source_files))
|
||||||
|
libc_asm_source_files = $(shell find src/libc/ -type f -name *.asm)
|
||||||
|
libc_asm_object_files = $(patsubst src/%.asm,obj/%.o,$(libc_c_object_files))
|
||||||
|
libc_source_files = $(libc_c_source_files) $(libc_asm_source_files)
|
||||||
|
libc_object_files = $(libc_c_object_files) $(libc_asm_object_files)
|
||||||
|
|
||||||
bin/kernel.bin: obj/kernel/entry.o ${CO_FILES} ${AO_FILES}
|
# Target: sboot, type: ASM
|
||||||
i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary
|
# Override: 32-bit
|
||||||
|
sboot_asm_source_files = $(shell find src/boot/ -type f -name *.asm)
|
||||||
|
sboot_asm_object_files = $(patsubst src/%.asm,obj/%.o,$(sboot_asm_source_files))
|
||||||
|
sboot_source_files = $(sboot_asm_source_files)
|
||||||
|
sboot_object_files = $(sboot_asm_object_files)
|
||||||
|
|
||||||
kernel.elf: obj/kernel/entry.o ${CO_FILES} ${AO_FILES}
|
shade_bin_ldfile = src/linker.ld
|
||||||
i386-elf-ld -o $@ -Ttext 0x1000 $^
|
|
||||||
|
|
||||||
run: clean os-image.bin
|
default: run
|
||||||
qemu-system-x86_64 -hdd os-image.bin
|
|
||||||
|
|
||||||
debug: clean os-image.bin kernel.elf
|
bin/shade.iso: bin/shade.bin
|
||||||
qemu-system-x86_64 -s -S -hdd os-image.bin &
|
cp bin/shade.bin src/iso/boot/shade.bin
|
||||||
${GDB} os-image.bin -ex "symbol-file kernel.elf" -ex "target remote localhost:1234"
|
grub-mkrescue src/iso/ -o $@
|
||||||
|
rm src/iso/boot/shade.bin
|
||||||
|
|
||||||
|
bin/shade.bin: $(sboot_object_files) $(kernel_object_files) $(libc_object_files)
|
||||||
|
mkdir -p "$(@D)"
|
||||||
|
$(LD) $(LDFLAGS) -n -T $(shade_bin_ldfile) $^ -o $@
|
||||||
|
grub-file --is-x86-multiboot2 $@
|
||||||
|
|
||||||
|
# Generics
|
||||||
|
# Source file types: C ASM
|
||||||
|
|
||||||
|
# C
|
||||||
obj/%.o: src/%.c
|
obj/%.o: src/%.c
|
||||||
mkdir -p "$(@D)"
|
mkdir -p "$(@D)"
|
||||||
i386-elf-gcc -g -ffreestanding -c $< -o $@
|
$(CC) $(CCFLAGS) -I $(INCLUDE) -ffreestanding -c $< -o $@
|
||||||
|
|
||||||
|
# ASM
|
||||||
obj/%.o: src/%.asm
|
obj/%.o: src/%.asm
|
||||||
mkdir -p "$(@D)"
|
mkdir -p "$(@D)"
|
||||||
nasm -f elf $< -o $@
|
$(ASM) -felf64 $< -o $@
|
||||||
|
|
||||||
bin/%.bin: src/%.asm
|
# Other
|
||||||
mkdir -p "$(@D)"
|
run: clean bin/shade.iso
|
||||||
nasm -f bin $< -o $@
|
qemu-system-x86_64 -drive file=bin/shade.iso,index=0,media=disk,format=raw
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
find obj -type f -name '*.o' -exec rm {} +
|
rm -rf bin/*
|
||||||
find obj -type f -name '*.bin' -exec rm {} +
|
rm -rf obj/*
|
||||||
find bin -type f -name '*.o' -exec rm {} +
|
|
||||||
find bin -type f -name '*.bin' -exec rm {} +
|
|
||||||
find . -type f -name '*.dis' -exec rm {} +
|
|
||||||
rm -f kernel.elf
|
|
BIN
bin/kernel.bin
BIN
bin/kernel.bin
Binary file not shown.
BIN
bin/shade.bin
Executable file
BIN
bin/shade.bin
Executable file
Binary file not shown.
BIN
bin/shade.iso
Normal file
BIN
bin/shade.iso
Normal file
Binary file not shown.
57
bochsrc.txt
Normal file
57
bochsrc.txt
Normal file
|
@ -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
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
56
old/Makefile
Normal file
56
old/Makefile
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# $@ = target file
|
||||||
|
# $< = first dependency
|
||||||
|
# $^ = all dependencies
|
||||||
|
|
||||||
|
GDB = gdb
|
||||||
|
|
||||||
|
C_FILES = $(shell find src/ -type f -name '*.c')
|
||||||
|
CO_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES))
|
||||||
|
ASM_FILES = $(shell find src/kernel/ -type f -name '*.asm')
|
||||||
|
AO_FILES = $(patsubst src/kernel/%.asm, obj/kernel/%.o, $(ASM_FILES))
|
||||||
|
ABIN_FILES = $(patsubst src/%.asm, bin/%.bin, $(ASM_FILES))
|
||||||
|
|
||||||
|
os-image.bin: bin/boot.bin bin/kernel.bin
|
||||||
|
cat $^ > $@
|
||||||
|
|
||||||
|
bin/boot.bin: src/boot/boot.asm bin/kernel.bin .FORCE
|
||||||
|
sed -i.orig "s@CH_REPLACE_BOOTSECTORCOUNT@$(shell ./getinblocks.py $(shell du -b "bin/kernel.bin" | cut -f 1))@g" src/boot/kernel.asm
|
||||||
|
nasm -Isrc/boot/ $< -f bin -o $@
|
||||||
|
mv src/boot/kernel.asm.orig src/boot/kernel.asm
|
||||||
|
|
||||||
|
.FORCE:
|
||||||
|
|
||||||
|
bin/kernel.bin: obj/kernel/entry.o ${CO_FILES} ${AO_FILES}
|
||||||
|
i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary
|
||||||
|
|
||||||
|
kernel.elf: obj/kernel/entry.o ${CO_FILES} ${AO_FILES}
|
||||||
|
i386-elf-ld -o $@ -Ttext 0x1000 $^
|
||||||
|
|
||||||
|
run: clean os-image.bin
|
||||||
|
qemu-system-x86_64 -hdd os-image.bin -d int
|
||||||
|
|
||||||
|
debug: clean os-image.bin kernel.elf
|
||||||
|
qemu-system-x86_64 -s -S -hdd os-image.bin &
|
||||||
|
${GDB} os-image.bin -ex "symbol-file kernel.elf" -ex "target remote localhost:1234"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
obj/%.o: src/%.c
|
||||||
|
mkdir -p "$(@D)"
|
||||||
|
i386-elf-gcc -g -ffreestanding -c $< -o $@
|
||||||
|
|
||||||
|
obj/%.o: src/%.asm
|
||||||
|
mkdir -p "$(@D)"
|
||||||
|
nasm -f elf $< -o $@
|
||||||
|
|
||||||
|
bin/%.bin: src/%.asm
|
||||||
|
mkdir -p "$(@D)"
|
||||||
|
nasm -f bin $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
find obj -type f -name '*.o' -exec rm {} +
|
||||||
|
find obj -type f -name '*.bin' -exec rm {} +
|
||||||
|
find bin -type f -name '*.o' -exec rm {} +
|
||||||
|
find bin -type f -name '*.bin' -exec rm {} +
|
||||||
|
find . -type f -name '*.dis' -exec rm {} +
|
||||||
|
rm -f kernel.elf
|
Binary file not shown.
BIN
old/bin/kernel.bin
Executable file
BIN
old/bin/kernel.bin
Executable file
Binary file not shown.
BIN
old/obj/kernel/kernel.o
Normal file
BIN
old/obj/kernel/kernel.o
Normal file
Binary file not shown.
BIN
old/obj/kernel/platform/interrupts/int.o
Normal file
BIN
old/obj/kernel/platform/interrupts/int.o
Normal file
Binary file not shown.
BIN
old/obj/kernel/platform/interrupts/int_lowlevel.o
Normal file
BIN
old/obj/kernel/platform/interrupts/int_lowlevel.o
Normal file
Binary file not shown.
BIN
old/obj/kernel/print.o
Normal file
BIN
old/obj/kernel/print.o
Normal file
Binary file not shown.
BIN
old/obj/kernel/util.o
Normal file
BIN
old/obj/kernel/util.o
Normal file
Binary file not shown.
BIN
old/os-image.bin
Normal file
BIN
old/os-image.bin
Normal file
Binary file not shown.
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
gdt_start: ; use labels to compute sizes and jumps
|
gdt_start: ; use labels to compute sizes and jumps
|
||||||
; gdt starts with 8 byte null
|
; gdt starts with 8 byte null
|
||||||
dd 0x0
|
dd 0x0
|
||||||
|
@ -14,12 +15,12 @@ gdt_code:
|
||||||
|
|
||||||
; GDT for data segment
|
; GDT for data segment
|
||||||
gdt_data:
|
gdt_data:
|
||||||
dw 0xffff
|
dw 0xffff ; segment length
|
||||||
dw 0x0
|
dw 0x0 ; segment base
|
||||||
db 0x0
|
db 0x0 ; segment base
|
||||||
db 10010010b
|
db 10010010b ; flags
|
||||||
db 11001111b
|
db 11001111b ; flags + segment length
|
||||||
db 0x0
|
db 0x0 ; segment base
|
||||||
|
|
||||||
gdt_end:
|
gdt_end:
|
||||||
|
|
54
old/src/kernel/kernel.c
Normal file
54
old/src/kernel/kernel.c
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "./platform/drivers/ports.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "./platform/types.h"
|
||||||
|
#include "./platform/interrupts/int.h"
|
||||||
|
|
||||||
|
void dummy_test_entrypoint() {}
|
||||||
|
|
||||||
|
void kernel_welcome() {
|
||||||
|
print_str("Welcome to ");
|
||||||
|
print_set_color(PRINT_COLOR_CYAN, PRINT_COLOR_BLACK);
|
||||||
|
print_str("Shade");
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
||||||
|
print_str("!\n");
|
||||||
|
|
||||||
|
print_str("shadeOS kernel version ");
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK);
|
||||||
|
print_str("0.2.2");
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
||||||
|
print_newline();
|
||||||
|
|
||||||
|
print_str("Running on ");
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK);
|
||||||
|
print_str("shade-development");
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
||||||
|
|
||||||
|
print_newline();
|
||||||
|
}
|
||||||
|
|
||||||
|
// kMain
|
||||||
|
void main() {
|
||||||
|
// Initialize screen buffer
|
||||||
|
struct Char* buffer = (struct Char*) 0xb8000;
|
||||||
|
|
||||||
|
clear_all(); // Clear screen
|
||||||
|
set_cursor_pos(0, 0); // Set cursor position
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set print color
|
||||||
|
|
||||||
|
// welcome messages
|
||||||
|
kernel_msg_ok("Initialized display successfully\n");
|
||||||
|
kernel_welcome();
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
4
old/src/kernel/platform/drivers/ports.h
Normal file
4
old/src/kernel/platform/drivers/ports.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
unsigned char port_byte_in(unsigned short port);
|
||||||
|
void port_byte_out(unsigned short port, unsigned char data);
|
||||||
|
unsigned short port_word_in(unsigned short port);
|
||||||
|
void port_word_out(unsigned short port, unsigned short data);
|
28
old/src/kernel/platform/gdt.h
Normal file
28
old/src/kernel/platform/gdt.h
Normal file
|
@ -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
|
|
@ -1,8 +1,14 @@
|
||||||
#include "int.h"
|
#include "int.h"
|
||||||
#include "../../print.h"
|
#include "../../print.h"
|
||||||
|
|
||||||
void exception_handler() {
|
int count = 0;
|
||||||
|
|
||||||
|
void exception_handler(registers_t r) {
|
||||||
print_str("I");
|
print_str("I");
|
||||||
|
count++;
|
||||||
|
if (count > 4) {
|
||||||
|
__asm__ __volatile__("cli; hlt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void idt_set_descriptor(u8 vector, void* isr, u8 flags) {
|
void idt_set_descriptor(u8 vector, void* isr, u8 flags) {
|
|
@ -21,8 +21,15 @@ typedef struct {
|
||||||
|
|
||||||
static idtr_t idtr;
|
static idtr_t idtr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 ds; /* Data segment selector */
|
||||||
|
u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
|
||||||
|
u32 int_no, err_code; /* Interrupt number and error code (if applicable) */
|
||||||
|
u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */
|
||||||
|
} registers_t;
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
void exception_handler(void);
|
void exception_handler(registers_t r);
|
||||||
|
|
||||||
void idt_set_descriptor(u8 vector, void* isr, u8 flags);
|
void idt_set_descriptor(u8 vector, void* isr, u8 flags);
|
||||||
|
|
102
old/src/kernel/platform/interrupts/int_lowlevel.asm
Normal file
102
old/src/kernel/platform/interrupts/int_lowlevel.asm
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
%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
|
||||||
|
sti
|
||||||
|
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
|
||||||
|
|
110
old/src/kernel/print.c
Normal file
110
old/src/kernel/print.c
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
#include "print.h"
|
||||||
|
#include "./platform/drivers/ports.h"
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
int col = 0;
|
||||||
|
char color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4;
|
||||||
|
|
||||||
|
void clear_row(int row) {
|
||||||
|
struct Char* buffer = (struct Char*) 0xb8000;
|
||||||
|
|
||||||
|
struct Char empty = (struct Char) {
|
||||||
|
character: ' ',
|
||||||
|
color: color,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int x = 0; x < NUM_COLS; x++) {
|
||||||
|
buffer[x + NUM_COLS * row] = empty;
|
||||||
|
}
|
||||||
|
set_cursor_pos(col, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_all() {
|
||||||
|
for (int i = 0; i < NUM_ROWS; i++) {
|
||||||
|
clear_row(i);
|
||||||
|
}
|
||||||
|
set_cursor_pos(col, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_newline() {
|
||||||
|
struct Char* buffer = (struct Char*) 0xb8000;
|
||||||
|
|
||||||
|
col = 0;
|
||||||
|
|
||||||
|
if (row < NUM_ROWS - 1) {
|
||||||
|
row++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int row = 1; row < NUM_ROWS; row++) {
|
||||||
|
for (int col = 0; col < NUM_COLS; col++) {
|
||||||
|
struct Char character = buffer[col + NUM_COLS * row];
|
||||||
|
buffer[col + NUM_COLS * (row - 1)] = character;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_row(NUM_COLS - 1);
|
||||||
|
set_cursor_pos(col, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_char(char character) {
|
||||||
|
struct Char* buffer = (struct Char*) 0xb8000;
|
||||||
|
|
||||||
|
if (character == '\n') {
|
||||||
|
print_newline();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col > NUM_COLS) {
|
||||||
|
print_newline();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Char cr = (struct Char) {
|
||||||
|
character: character,
|
||||||
|
color: color,
|
||||||
|
};
|
||||||
|
buffer[col + NUM_COLS * row] = cr;
|
||||||
|
|
||||||
|
col++;
|
||||||
|
set_cursor_pos(col, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_str(char* str) {
|
||||||
|
for (int i = 0; 1; i++) {
|
||||||
|
char character = (char) str[i];
|
||||||
|
|
||||||
|
if (character == '\0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_char(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_set_color(char foreground, char background) {
|
||||||
|
color = foreground + (background << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_cursor_pos(int col, int row) {
|
||||||
|
int offset = col + NUM_COLS * row;
|
||||||
|
port_byte_out(REG_SCREEN_CTRL, 14);
|
||||||
|
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8));
|
||||||
|
port_byte_out(REG_SCREEN_CTRL, 15);
|
||||||
|
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernel_msg_ok(char* msg) {
|
||||||
|
char ok_p1[] = "[ ";
|
||||||
|
char ok_p2[] = "OK ";
|
||||||
|
char ok_p3[] = "] ";
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
||||||
|
print_str(ok_p1);
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
|
||||||
|
print_str(ok_p2);
|
||||||
|
|
||||||
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
|
||||||
|
print_str(ok_p3);
|
||||||
|
print_str(msg);
|
||||||
|
}
|
44
old/src/kernel/print.h
Normal file
44
old/src/kernel/print.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef PRINT_H
|
||||||
|
#define PRINT_H
|
||||||
|
#define REG_SCREEN_CTRL 0x3d4
|
||||||
|
#define REG_SCREEN_DATA 0x3d5
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PRINT_COLOR_BLACK = 0,
|
||||||
|
PRINT_COLOR_BLUE = 1,
|
||||||
|
PRINT_COLOR_GREEN = 2,
|
||||||
|
PRINT_COLOR_CYAN = 3,
|
||||||
|
PRINT_COLOR_RED = 4,
|
||||||
|
PRINT_COLOR_MAGENTA = 5,
|
||||||
|
PRINT_COLOR_BROWN = 6,
|
||||||
|
PRINT_COLOR_LIGHT_GRAY = 7,
|
||||||
|
PRINT_COLOR_DARK_GRAY = 8,
|
||||||
|
PRINT_COLOR_LIGHT_BLUE = 9,
|
||||||
|
PRINT_COLOR_LIGHT_GREEN = 10,
|
||||||
|
PRINT_COLOR_LIGHT_CYAN = 11,
|
||||||
|
PRINT_COLOR_LIGHT_RED = 12,
|
||||||
|
PRINT_COLOR_PINK = 13,
|
||||||
|
PRINT_COLOR_YELLOW = 14,
|
||||||
|
PRINT_COLOR_WHITE = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
const static int NUM_COLS = 80;
|
||||||
|
const static int NUM_ROWS = 25;
|
||||||
|
|
||||||
|
struct Char {
|
||||||
|
char character;
|
||||||
|
char color;
|
||||||
|
};
|
||||||
|
|
||||||
|
void clear_row(int row);
|
||||||
|
void clear_all();
|
||||||
|
|
||||||
|
void print_newline();
|
||||||
|
void print_char(char character);
|
||||||
|
void print_set_color(char foreground, char background);
|
||||||
|
void print_str(char* str);
|
||||||
|
|
||||||
|
void set_cursor_pos(int col, int row);
|
||||||
|
|
||||||
|
void kernel_msg_ok(char* msg);
|
||||||
|
#endif
|
10
old/src/kernel/strings.h
Normal file
10
old/src/kernel/strings.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef STRINGS_H
|
||||||
|
#define STRINGS_H
|
||||||
|
|
||||||
|
void itoa(int n, char str[]);
|
||||||
|
void strrev(char s[]);
|
||||||
|
int strlen(char s[]);
|
||||||
|
char* strcpy(char* strDest, const char* strSrc);
|
||||||
|
char* strcnc(char* str1, char* str2);
|
||||||
|
|
||||||
|
#endif
|
25
old/src/kernel/util.c
Normal file
25
old/src/kernel/util.c
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
void memcpy(char *source, char *dest, int nbytes) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nbytes; i++) {
|
||||||
|
*(dest + i) = *(source + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void memset(char *dest, char val, int len) {
|
||||||
|
char *temp = (char *)dest;
|
||||||
|
for(; len !=0; len--) *temp++ = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void int_to_ascii(int n, char str[]) {
|
||||||
|
int i, sign;
|
||||||
|
if ((sign = n) < 0) n = -n;
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
str[i++] = n % 10 + '0';
|
||||||
|
} while ((n /= 10) > 0);
|
||||||
|
|
||||||
|
if (sign < 0) str[i++] = '-';
|
||||||
|
str[i] = '\0';
|
||||||
|
}
|
8
old/src/kernel/util.h
Normal file
8
old/src/kernel/util.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef UTIL_H
|
||||||
|
#define UTIL_H
|
||||||
|
|
||||||
|
void memcpy(char *source, char *dest, int nbytes);
|
||||||
|
void memset(char *dest, char val, int len);
|
||||||
|
void int_to_ascii(int n, char str[]);
|
||||||
|
|
||||||
|
#endif
|
BIN
os-image.bin
BIN
os-image.bin
Binary file not shown.
141
src/boot/entry.asm
Normal file
141
src/boot/entry.asm
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
|
||||||
|
|
||||||
|
global entry_x86
|
||||||
|
extern entry_x64
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 32
|
||||||
|
entry_x86:
|
||||||
|
mov esp, stack_top
|
||||||
|
|
||||||
|
call check_mb2_boot
|
||||||
|
call check_cpuid
|
||||||
|
call check_x64_supported
|
||||||
|
|
||||||
|
call setup_page_tables
|
||||||
|
call enable_paging
|
||||||
|
|
||||||
|
lgdt [gdt64.pointer]
|
||||||
|
jmp gdt64.code_segment:entry_x64 ; Jump into 64 bit entry
|
||||||
|
|
||||||
|
hlt
|
||||||
|
|
||||||
|
check_mb2_boot:
|
||||||
|
cmp eax, 0x36d76289 ; compare eax to mb2 magic number
|
||||||
|
jne .mb2_not_booted
|
||||||
|
ret
|
||||||
|
.mb2_not_booted:
|
||||||
|
mov al, "B" ; err code B - boot error
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
check_cpuid:
|
||||||
|
pushfd ; Put flags on stack so we can mess with them
|
||||||
|
pop eax ; then put the stack into EAX so we can easily modify it
|
||||||
|
mov ecx, eax ; Make a copy of eax in ecx for comparison
|
||||||
|
xor eax, 1 << 21 ; Attempt to flip the CPUID bit which is bit 21
|
||||||
|
push eax ; Put eax back onto stack
|
||||||
|
popfd ; Write flags back
|
||||||
|
pushfd ; Copy flags onto stack so we can check if the bit did flip
|
||||||
|
pop eax ; Put stack into EAX for comparison
|
||||||
|
push ecx ; Put original flags into stack so we can make sure they remain unchanged
|
||||||
|
popfd; Push original flags back onto the flags register
|
||||||
|
cmp eax, ecx ; Compare the modifided? flags to the original flags
|
||||||
|
je .cpuid_unsupported ; Flags were not changed, cpuid not supported
|
||||||
|
ret
|
||||||
|
|
||||||
|
.cpuid_unsupported:
|
||||||
|
mov al, "C" ; err code C - cpuid unsupported
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
check_x64_supported:
|
||||||
|
mov eax, 0x80000000 ; Magic code that i dont understand
|
||||||
|
cpuid ; Magic code that i dont understand
|
||||||
|
cmp eax, 0x80000001 ; Magic code that i dont undetstand
|
||||||
|
jb .x64_unsupported ; Something went wrong so x64 isnt supported
|
||||||
|
|
||||||
|
mov eax, 0x80000001 ; Set magic value 0x80000001 into EAX for cpuid
|
||||||
|
cpuid ; Get "extended features list" from CPU info
|
||||||
|
test edx, 1 << 29 ; Check if x64 is supported by checking bit 29
|
||||||
|
jz .x64_unsupported ; If zero, x64 unsupported so jump to no x64
|
||||||
|
|
||||||
|
ret
|
||||||
|
.x64_unsupported:
|
||||||
|
mov al, "L" ; err code L, long mode/x64 unsupported
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
; Magic paging code that I don't understand
|
||||||
|
setup_page_tables:
|
||||||
|
mov eax, page_table_l3
|
||||||
|
or eax, 0b11 ; present, writable
|
||||||
|
mov [page_table_l4], eax
|
||||||
|
|
||||||
|
mov eax, page_table_l2
|
||||||
|
or eax, 0b11 ; present, writable
|
||||||
|
mov [page_table_l3], eax
|
||||||
|
|
||||||
|
mov ecx, 0 ; counter
|
||||||
|
.loop:
|
||||||
|
|
||||||
|
mov eax, 0x200000 ; 2MiB
|
||||||
|
mul ecx
|
||||||
|
or eax, 0b10000011 ; present, writable, huge page
|
||||||
|
mov [page_table_l2 + ecx * 8], eax
|
||||||
|
|
||||||
|
inc ecx ; increment counter
|
||||||
|
cmp ecx, 512 ; checks if the whole table is mapped
|
||||||
|
jne .loop ; if not, continue
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
enable_paging:
|
||||||
|
; pass page table location to cpu
|
||||||
|
mov eax, page_table_l4
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
; enable PAE
|
||||||
|
mov eax, cr4
|
||||||
|
or eax, 1 << 5
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
; enable long mode
|
||||||
|
mov ecx, 0xC0000080
|
||||||
|
rdmsr
|
||||||
|
or eax, 1 << 8
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
; enable paging
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 << 31
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
error:
|
||||||
|
; print "ERR: X" where X is the error code
|
||||||
|
mov dword [0xb8000], 0x4f524f45
|
||||||
|
mov dword [0xb8004], 0x4f3a4f52
|
||||||
|
mov dword [0xb8008], 0x4f204f20
|
||||||
|
mov byte [0xb800a], al
|
||||||
|
hlt
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
align 4096
|
||||||
|
page_table_l4:
|
||||||
|
resb 4096
|
||||||
|
page_table_l3:
|
||||||
|
resb 4096
|
||||||
|
page_table_l2:
|
||||||
|
resb 4096
|
||||||
|
stack_bottom:
|
||||||
|
resb 4096 * 4
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
section .rodata
|
||||||
|
gdt64:
|
||||||
|
dd 0 ; zero entry
|
||||||
|
dd 0
|
||||||
|
.code_segment: equ $ - gdt64
|
||||||
|
dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment
|
||||||
|
.pointer:
|
||||||
|
dw $ - gdt64 - 1 ; length
|
||||||
|
dq gdt64 ; address
|
17
src/boot/entry64.asm
Normal file
17
src/boot/entry64.asm
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
global entry_x64
|
||||||
|
extern kmain
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 64
|
||||||
|
entry_x64:
|
||||||
|
; Nullify all data registers
|
||||||
|
mov ax, 0
|
||||||
|
mov ss, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
call kmain ; Jump into C kernel entry
|
||||||
|
|
||||||
|
hlt
|
16
src/boot/mb2_header.asm
Normal file
16
src/boot/mb2_header.asm
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
section .mb2_header
|
||||||
|
header_start:
|
||||||
|
; https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html for more information, section 3.1.1
|
||||||
|
dd 0xe85250d6 ; multiboot2 magic number
|
||||||
|
|
||||||
|
dd 0 ; i386 protected 32 bit mode
|
||||||
|
|
||||||
|
dd header_end - header_start ; Header length
|
||||||
|
|
||||||
|
dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) ; Checksum, total is 0
|
||||||
|
|
||||||
|
; Ending tag
|
||||||
|
dw 0
|
||||||
|
dw 0
|
||||||
|
dd 8
|
||||||
|
header_end:
|
7
src/iso/boot/grub/grub.cfg
Normal file
7
src/iso/boot/grub/grub.cfg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
set timeout=5
|
||||||
|
set default=0
|
||||||
|
|
||||||
|
menuentry "shadeOS Development Build" {
|
||||||
|
multiboot2 /boot/shade.bin
|
||||||
|
boot
|
||||||
|
}
|
|
@ -1,9 +1,5 @@
|
||||||
#include "./platform/drivers/ports.h"
|
#include <shade/platform/ports.h>
|
||||||
#include "print.h"
|
#include <shade/print.h>
|
||||||
#include "./platform/types.h"
|
|
||||||
#include "./platform/interrupts/int.h"
|
|
||||||
|
|
||||||
void dummy_test_entrypoint() {}
|
|
||||||
|
|
||||||
void kernel_welcome() {
|
void kernel_welcome() {
|
||||||
print_str("Welcome to ");
|
print_str("Welcome to ");
|
||||||
|
@ -31,7 +27,7 @@ void kernel_welcome() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// kMain
|
// kMain
|
||||||
void main() {
|
void kmain() {
|
||||||
// Initialize screen buffer
|
// Initialize screen buffer
|
||||||
struct Char* buffer = (struct Char*) 0xb8000;
|
struct Char* buffer = (struct Char*) 0xb8000;
|
||||||
|
|
||||||
|
@ -47,8 +43,4 @@ void main() {
|
||||||
print_str("This program is provided \"as-is\" and no express or implied warranty is provided.\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");
|
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");
|
|
||||||
}
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
%macro isr_err_stub 1
|
|
||||||
isr_stub_%+%1:
|
|
||||||
call exception_handler
|
|
||||||
iret
|
|
||||||
%endmacro
|
|
||||||
; if writing for 64-bit, use iretq instead
|
|
||||||
%macro isr_no_err_stub 1
|
|
||||||
isr_stub_%+%1:
|
|
||||||
call exception_handler
|
|
||||||
iret
|
|
||||||
%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
|
|
||||||
|
|
26
src/kernel/platform/ports.c
Normal file
26
src/kernel/platform/ports.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Read 1 byte from specified port
|
||||||
|
*/
|
||||||
|
unsigned char port_byte_in(unsigned short port) {
|
||||||
|
unsigned char result;
|
||||||
|
// source and dest are backwards.
|
||||||
|
// "=a (result)" set the C variable to the value of register e'a'x
|
||||||
|
// '"d" (port) map the C variable port into e'd'x register
|
||||||
|
__asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
|
||||||
|
}
|
||||||
|
|
||||||
|
void port_byte_out(unsigned short port, unsigned char data) {
|
||||||
|
// both regs are C vars, nothing is returned, so no '=' in asm syntax
|
||||||
|
// comma because two vars in input area and none in return area
|
||||||
|
__asm__("out %%al, %%dx" : : "a" (data), "d" (port));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short port_word_in(unsigned short port) {
|
||||||
|
unsigned short result;
|
||||||
|
__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void port_word_out(unsigned short port, unsigned short data) {
|
||||||
|
__asm__("out %%ax, %%dx" : : "a" (data), "d" (port));
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#include "print.h"
|
#include <shade/print.h>
|
||||||
#include "./platform/drivers/ports.h"
|
#include <shade/platform/ports.h>
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "util.h"
|
#include <shade/util.h>
|
||||||
|
|
||||||
void memcpy(char *source, char *dest, int nbytes) {
|
void memcpy(char *source, char *dest, int nbytes) {
|
||||||
int i;
|
int i;
|
||||||
|
|
48
src/libc/strings.c
Normal file
48
src/libc/strings.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#include <strings.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void itoa(int n, char str[]) {
|
||||||
|
int i, sign;
|
||||||
|
if ((sign = n) < 0) n = -n;
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
str[i++] = n % 10 + '0';
|
||||||
|
} while ((n /= 10) > 0);
|
||||||
|
|
||||||
|
if (sign < 0) str[i++] = '-';
|
||||||
|
str[i] = '\0';
|
||||||
|
|
||||||
|
strrev(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* K&R */
|
||||||
|
void strrev(char s[]) {
|
||||||
|
int c, i, j;
|
||||||
|
for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
|
||||||
|
c = s[i];
|
||||||
|
s[i] = s[j];
|
||||||
|
s[j] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* K&R */
|
||||||
|
int strlen(char s[]) {
|
||||||
|
int i = 0;
|
||||||
|
while (s[i] != '\0') ++i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strcpy(char* strDest, const char* strSrc) {
|
||||||
|
if ( (strDest == NULL) || (strSrc == NULL) ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char* strDestCopy = strDest;
|
||||||
|
while ((*strDest++=*strSrc++)!='\0');
|
||||||
|
return strDestCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strcnc(char* str1, char* str2) {
|
||||||
|
char* str_dest;
|
||||||
|
strcpy(str_dest, str1);
|
||||||
|
strcpy(str_dest, str2);
|
||||||
|
}
|
30
src/linker.ld
Normal file
30
src/linker.ld
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
ENTRY(entry_x86)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 1M;
|
||||||
|
|
||||||
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.mb2_header)
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read-only data. */
|
||||||
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.rodata)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read-write data (initialized) */
|
||||||
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read-write data (uninitialized) and stack */
|
||||||
|
.bss BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue