prepare for transplanting of new shade into shade64 base
This commit is contained in:
parent
35d08c3a9c
commit
e372c12dae
20
Makefile
20
Makefile
|
@ -1,7 +1,7 @@
|
|||
ASM ?= nasm
|
||||
CC := i686-elf-gcc
|
||||
GDB := i686-elf-gdb
|
||||
LD := i686-elf-ld
|
||||
CC := x86_64-elf-gcc
|
||||
GDB := gdb
|
||||
LD := x86_64-elf-ld
|
||||
|
||||
C_FILES = $(shell find src/ -type f -name '*.c')
|
||||
CO_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES))
|
||||
|
@ -10,15 +10,15 @@ AO_FILES = $(patsubst src/kernel/%.asm, obj/kernel/%.o, $(ASM_FILES))
|
|||
|
||||
KERNEL_O_FILES = ${CO_FILES} ${AO_FILES}
|
||||
|
||||
BOOT_O_FILES = obj/entry.o obj/entry64.o obj/mb2.o obj/vga-print.o
|
||||
BOOT_SRC_FILES = obj/entry.asm obj/entry64.asm obj/mb2.asm obj/vga-print.asm
|
||||
|
||||
iso: bin/shade.iso
|
||||
|
||||
obj/boot.o: src/boot.asm
|
||||
$(ASM) -felf32 $^ -o $@
|
||||
|
||||
bin/shade.bin: obj/boot.o ${KERNEL_O_FILES}
|
||||
bin/shade.bin: ${BOOT_O_FILES} ${KERNEL_O_FILES}
|
||||
mkdir -p bin
|
||||
$(CC) -T src/linker.ld -ffreestanding -O2 -nostdlib $^ -o $@ -lgcc
|
||||
grub-file --is-x86-multiboot bin/shade.bin
|
||||
$(LD) -T src/linker.ld $^ -o $@
|
||||
grub-file --is-x86-multiboot2 bin/shade.bin
|
||||
|
||||
bin/shade.iso: bin/shade.bin
|
||||
mkdir -p isodir/boot/grub
|
||||
|
@ -33,7 +33,7 @@ obj/%.o: src/%.c
|
|||
|
||||
obj/%.o: src/%.asm
|
||||
mkdir -p "$(@D)"
|
||||
$(ASM) -f elf $< -o $@
|
||||
$(ASM) -f elf64 $< -o $@
|
||||
|
||||
|
||||
run: clean bin/shade.iso
|
||||
|
|
BIN
bin/shade.bin
BIN
bin/shade.bin
Binary file not shown.
BIN
bin/shade.iso
BIN
bin/shade.iso
Binary file not shown.
BIN
obj/boot.o
BIN
obj/boot.o
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
52
src/boot.asm
52
src/boot.asm
|
@ -1,52 +0,0 @@
|
|||
; Declare constants for the multiboot header.
|
||||
MBALIGN equ 1 << 0 ; align loaded modules on page boundaries
|
||||
MEMINFO equ 1 << 1 ; provide memory map
|
||||
FLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field
|
||||
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
|
||||
CHECKSUM equ -(MAGIC + FLAGS) ; checksum of above, to prove we are multiboot
|
||||
|
||||
section .multiboot
|
||||
align 4
|
||||
dd MAGIC
|
||||
dd FLAGS
|
||||
dd CHECKSUM
|
||||
|
||||
section .bss
|
||||
align 16
|
||||
|
||||
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
|
||||
|
||||
global _start:function (_start.end - _start)
|
||||
_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
|
||||
|
||||
cli ; Turn off interrupts in case they are on
|
||||
.hang:
|
||||
hlt ; Totally halt the cpu
|
||||
jmp .hang ; If the cpu un-halts for some reason, halt again
|
||||
|
||||
.end:
|
33
src/gdt.asm
33
src/gdt.asm
|
@ -1,33 +0,0 @@
|
|||
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,6 +1,5 @@
|
|||
#include "./platform/drivers/ports.h"
|
||||
#include "./platform/ports.h"
|
||||
#include "print.h"
|
||||
#include "./platform/interrupts/int.h"
|
||||
|
||||
void dummy_test_entrypoint() {}
|
||||
|
||||
|
@ -45,10 +44,4 @@ 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();
|
||||
|
||||
__asm__ __volatile__("int $2");
|
||||
|
||||
//kernel_msg_ok("Interrupts working");
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* 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,4 +0,0 @@
|
|||
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);
|
|
@ -1,35 +0,0 @@
|
|||
#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
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
#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
|
|
@ -1,101 +0,0 @@
|
|||
%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,5 +1,5 @@
|
|||
#include "print.h"
|
||||
#include "./platform/drivers/ports.h"
|
||||
#include "./platform/ports.h"
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
@ -87,10 +87,10 @@ void print_set_color(char foreground, char background) {
|
|||
|
||||
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));
|
||||
outb(REG_SCREEN_CTRL, 14);
|
||||
outb(REG_SCREEN_DATA, (unsigned char)(offset >> 8));
|
||||
outb(REG_SCREEN_CTRL, 15);
|
||||
outb(REG_SCREEN_DATA, (unsigned char)(offset & 0xff));
|
||||
}
|
||||
|
||||
void kernel_msg_ok(char* msg) {
|
||||
|
|
|
@ -1,32 +1,23 @@
|
|||
ENTRY(_start)
|
||||
|
||||
ENTRY(entry_x86)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 1M;
|
||||
. = 1M;
|
||||
|
||||
/* MB header */
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
.boot :
|
||||
{
|
||||
KEEP(*(.mb2_header))
|
||||
}
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
/* Read-only data. */
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
.idt BLOCK(0x1000) : ALIGN(0x1000)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
/* Read-write data (initialized) */
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
/* Read-write data (uninitialized) and stack */
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
_idt = .;
|
||||
. = . + 0x1000;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue