feat(kernel): WIP higher half kernel

This commit is contained in:
d0p1 🏳️‍⚧️ 2023-07-02 16:47:18 +02:00
parent 8cefd7946f
commit 5cccfa22d4
29 changed files with 644 additions and 251 deletions

View file

@ -4,10 +4,28 @@ export TOPDIR
SUBDIR := thirdparty lib bin kernel SUBDIR := thirdparty lib bin kernel
CLEANFILES += stupid.iso stupid.tar.gz
.PHONY: docs .PHONY: docs
docs: docs:
-mkdir -p docs/html -mkdir -p docs/html
naturaldocs -p docs/config -img docs/img -xi tmp -i . -o HTML docs/html naturaldocs -p docs/config -img docs/img -xi tmp -i . -o HTML docs/html
cp docs/img/favicon.ico docs/html/ cp docs/img/favicon.ico docs/html/
.PHONY: stupid.iso
stupid.iso:
$(MAKE) all
DESTDIR=$(TOPDIR)/sysroot $(MAKE) install
$(TOPDIR)/tools/create-iso $@ sysroot
.PHONY: stupid.tar.gz
stupid.tar.gz:
$(MAKE) all
DESTDIR=$(TOPDIR)/sysroot $(MAKE) install
tar -czvf $@ sysroot
run: stupid.iso
qemu-system-i386 -cdrom $< -serial stdio
include $(TOPDIR)/share/mk/stupid.subdir.mk include $(TOPDIR)/share/mk/stupid.subdir.mk
include $(TOPDIR)/share/mk/stupid.clean.mk

View file

@ -45,29 +45,49 @@ File: FAQ (docs/faq.txt)
Group: Kernel { Group: Kernel {
File: head.s (kernel/head.s) Group: Boot {
File: feat.s (kernel/boot/feat.s)
File: head.s (kernel/boot/head.s)
} # Group: Boot
File: gdt.s (kernel/gdt.s) File: gdt.s (kernel/gdt.s)
File: idt.s (kernel/idt.s) File: idt.s (kernel/idt.s)
File: multiboot.inc (kernel/multiboot.inc)
File: pic.s (kernel/pic.s) File: pic.s (kernel/pic.s)
File: paging.s (no auto-title, kernel/paging.s)
Group: Driver { Group: Driver {
File: serial.s (no auto-title, kernel/drivers/serial.s) File: serial.s (no auto-title, kernel/drivers/serial.s)
} # Group: Driver } # Group: Driver
Group: i18n {
File: msg_en.s (kernel/i18n/msg_en.s)
} # Group: i18n
File: kernel.s (kernel/kernel.s) File: kernel.s (kernel/kernel.s)
File: msg_en (kernel/i18n/msg_en.s)
File: pmm.s (kernel/pmm.s) File: pmm.s (kernel/pmm.s)
Group: Sys {
File: multiboot.inc (kernel/sys/multiboot.inc)
Group: I386 {
File: cpuid.inc (kernel/sys/i386/cpuid.inc)
File: mmu.inc (kernel/sys/i386/mmu.inc)
File: registers.inc (kernel/sys/i386/registers.inc)
} # Group: I386
} # Group: Sys
} # Group: Kernel } # Group: Kernel
Group: Lib { Group: Lib {
File: base.inc (lib/base.inc)
Group: Base { Group: Base {
File: base.inc (lib/base/base.inc)
File: log.s (lib/base/log.s) File: log.s (lib/base/log.s)
} # Group: Base } # Group: Base

View file

@ -1,5 +1,10 @@
KERNEL = vmstupid KERNEL = vmstupid
SRCS = head.s gdt.s pic.s isr.s idt.s pmm.s paging.s \ SRCS = boot/head.s boot/feat.s kernel.s gdt.s pic.s isr.s idt.s pmm.s paging.s \
lib/log.s drivers/serial.s lib/log.s drivers/serial.s
INCS = sys/multiboot.inc \
sys/i386/cpuid.inc \
sys/i386/mmu.inc \
sys/i386/registers.inc
include $(TOPDIR)/share/mk/stupid.kernel.mk include $(TOPDIR)/share/mk/stupid.kernel.mk
include $(TOPDIR)/share/mk/stupid.inc.mk

55
kernel/boot/feat.s Normal file
View file

@ -0,0 +1,55 @@
;; File: feat.s
%include "machdep.inc"
%include "sys/i386/registers.inc"
%include "sys/i386/cpuid.inc"
%include "sys/i386/mmu.inc"
section multiboot.text
extern machdep
;; Function: cpuid_detect
;; check if cpuid is avaible.
;;
;; ripped from <osdev wiki at https://wiki.osdev.org/CPUID#Checking_CPUID_availability>
cpuid_detect:
pushfd
pushfd
xor dword [esp], EFLAGS_ID
popfd
pushfd
pop eax
xor eax, [esp]
popfd
and eax, EFLAGS_ID
ret
;; Function: feat_detect
global feat_detect
feat_detect:
push ebp
mov ebp, esp
call cpuid_detect
test eax, eax
jz .has_cpuid
jmp .end
.has_cpuid:
mov byte [V2P(machdep) + machinfo.has_cpuid], 1
mov eax, CPUID_GETFEATURES
cpuid
;; test if PSE is available
mov eax, edx
and eax, CPUID_FEAT_EDX_PSE
jz .end
mov byte [V2P(machdep) + machinfo.has_pse], 1
;; test if PAE is available (we won't support PAE for now)
mov eax, edx
and eax, CPUID_FEAT_EDX_PAE
jz .end
mov byte [V2P(machdep) + machinfo.has_pae], 1
.end:
leave
ret

69
kernel/boot/head.s Normal file
View file

@ -0,0 +1,69 @@
;; File: head.s
[BITS 32]
%include "machdep.inc"
%include "sys/multiboot.inc"
%include "sys/i386/registers.inc"
%include "sys/i386/mmu.inc"
;; Define: MB_HDR_FLAGS
MB_HDR_FLAGS equ MB_HDR_ALIGN | MB_HDR_MEMINFO | MB_HDR_VIDEO
section .multiboot.data
align 4
istruc mb_header
at mb_header.magic, dd MB_HDR_MAGIC
at mb_header.flags, dd MB_HDR_FLAGS
at mb_header.checksum, dd -(MB_HDR_MAGIC + MB_HDR_FLAGS)
; video mode info
at mb_header.mode_type, dd 0
at mb_header.width, dd 1024
at mb_header.height, dd 768
at mb_header.depth, dd 32
iend
section .multiboot.text
;; Function: entry
;;
;;
;; in:
;; EAX - Multiboot magic
;; EBX - Multiboot structure
;;
;; out:
;; none
;;
global entry
entry:
extern stack_top
mov esp, V2P(stack_top)
;; save boot params
mov edi, eax
mov esi, ebx
extern feat_detect
call feat_detect
;; setup 4MB paging
;; TODO: check if 4MB paging is available
mov eax, cr4
or eax, CR4_PSE
mov cr4, eax
extern page_directory
mov eax, V2P(page_directory)
mov cr3, eax
;; enable paging
mov eax, cr0
or eax, CR0_PG | CR0_PE | CR0_WP
mov cr0, eax
extern page_directory
mov eax, page_directory - KERNBASE
extern kernel_start
mov ebx, kernel_start

View file

@ -1,22 +1,58 @@
struc tss struc tss
.link: resd 1 .link: resw 1
resw 1
.esp0: resd 1
.ss0: resw 1
resw 1
.esp1: resd 1
.ss1: resw 1
resw 1
.esp2: resd 1
.ss2: resw 1
resw 1
.cr3: resd 1
.eip: resd 1
.eflags: resd 1
.eax: resd 1
.ecx: resd 1
.edx: resd 1
.ebx: resd 1
.esp: resd 1
.ebp: resd 1
.esi: resd 1
.edi: resd 1
.es: resw 1
resw 1
.cs: resw 1
resw 1
.ss: resw 1
resw 1
.ds: resw 1
resw 1
.fs: resw 1
resw 1
.gs: resw 1
resw 1
.ldtr: resw 1
resw 1
.iopb: resw 1
resw 1
endstruc endstruc
struc gdt_entry struc gdt_entry
.limit_low: resw 1 .limit_low: resw 1
.base_low: resw 1 .base_low: resw 1
.base_mid: resb 1 .base_mid: resb 1
.access: resb 1 .access: resb 1
.flags: resb 1 .flags: resb 1
.base_high: resb 1 .base_high: resb 1
endstruc endstruc
struc idt_entry struc idt_entry
.limit_low: resw 1 .limit_low: resw 1
.selector: resw 1 .selector: resw 1
.zero: resb 1 .zero: resb 1
.attr: resb 1 .attr: resb 1
.base_high: resw 1 .base_high: resw 1
endstruc endstruc
@ -32,20 +68,19 @@ struc intframe
.eax: resd 1 .eax: resd 1
;; ;;
.gs: resd 1 .gs: resd 1
.fs: resd 1 .fs: resd 1
.es: resd 1 .es: resd 1
.ds: resd 1 .ds: resd 1
.intno: resd 1 .intno: resd 1
;; by x86 hardware ;; by x86 hardware
.err: resd 1 .err: resd 1
.eip: resd 1 .eip: resd 1
.cs: resd 1 .cs: resd 1
.eflags: resd 1 .eflags: resd 1
;; crossring ;; crossring
.useresp: resd 1 .useresp: resd 1
.ss: resd 1 .ss: resd 1
endstruc endstruc

View file

@ -3,9 +3,12 @@
; ;
[BITS 32] [BITS 32]
%include "cpu.inc"
section .text section .text
; Function: setup_gdt
; Function: gdt_setup
; ;
; in: ; in:
; none ; none
@ -13,8 +16,8 @@ section .text
; out: ; out:
; none ; none
; ;
global setup_gdt global gdt_setup
setup_gdt: gdt_setup:
lgdt [gdt_ptr] lgdt [gdt_ptr]
mov eax, cr0 mov eax, cr0
or al, 1 or al, 1
@ -41,36 +44,49 @@ gdt_entries:
dd 0x0 dd 0x0
;; kernel mode code segment ;; kernel mode code segment
dw 0xFFFF ; Limit istruc gdt_entry
dw 0x0000 ; Base (low) at gdt_entry.limit_low, dw 0xFFFF
db 0x00 ; Base (mid) at gdt_entry.base_low, dw 0x0000
db 0x9A ; Access: 1 (P) 0 (DPL), 1 (S), 1010 (Type) at gdt_entry.base_mid, db 0x00
db 0xCF ; Granularity: 1 (G), 1 (D/B), 0 (AVL), Limit at gdt_entry.access, db 0x9A
db 0x00 ; Base (high) at gdt_entry.flags, db 0xCF
at gdt_entry.base_high, db 0x00
iend
;; kernel mode data segment ;; kernel mode data segment
dw 0xFFFF istruc gdt_entry
dw 0x0000 at gdt_entry.limit_low, dw 0xFFFF
db 0x00 at gdt_entry.base_low, dw 0x0000
db 0x92 at gdt_entry.base_mid, db 0x00
db 0xCF at gdt_entry.access, db 0x92
db 0x00 at gdt_entry.flags, db 0xCF
at gdt_entry.base_high, db 0x00
iend
;; user mode code segment ;; user mode code segment
dw 0xFFFF istruc gdt_entry
dw 0x0000 at gdt_entry.limit_low, dw 0xFFFF
db 0x00 at gdt_entry.base_low, dw 0x0000
db 0xFA at gdt_entry.base_mid, db 0x00
db 0xCF at gdt_entry.access, db 0xFA
db 0x00 at gdt_entry.flags, db 0xCF
at gdt_entry.base_high, db 0x00
iend
;; user mode data segment ;; user mode data segment
dw 0xFFFF istruc gdt_entry
dw 0x0000 at gdt_entry.limit_low, dw 0xFFFF
db 0x00 at gdt_entry.base_low, dw 0x0000
db 0xF2 at gdt_entry.base_mid, db 0x00
db 0xCF at gdt_entry.access, db 0xF2
db 0x00 at gdt_entry.flags, db 0xCF
at gdt_entry.base_high, db 0x00
iend
;;.tss:
;; TSS ;; TSS
;;istruc gdt_entry
;; at gdt_entry.access, db 0x89
;; at gdt_entry.flags, db 0x0
;;iend
.end: .end:

View file

@ -1,110 +0,0 @@
; file: head.s
;
[BITS 32]
%include "base.inc"
%include "multiboot.inc"
; Define: MB_HDR_FLAGS
MB_HDR_FLAGS equ MB_HDR_ALIGN | MB_HDR_MEMINFO | MB_HDR_VIDEO
section .multiboot
align 4
istruc mb_header
at mb_header.magic, dd MB_HDR_MAGIC
at mb_header.flags, dd MB_HDR_FLAGS
at mb_header.checksum, dd -(MB_HDR_MAGIC + MB_HDR_FLAGS)
; video mode info
at mb_header.mode_type, dd 0
at mb_header.width, dd 1024
at mb_header.height, dd 768
at mb_header.depth, dd 32
iend
section .bss
align 16
stack_bottom:
resb 16384
stack_top:
section .text
; Function: entry
; setup cpu and paging before calling <kmain>
;
; in:
; EAX - Multiboot magic
; EBX - Multiboot structure
;
; out:
; none
;
global entry
entry:
mov esp, stack_top
cli ; disable interrupt
mov edi, eax ; save multiboot magic in EDI
mov esi, ebx ; save multiboot structure in ESI
;; initialize serial (mostly used for debug)
extern serial_init
call serial_init
;; make sure we use a multiboot compliant bootloader
cmp edi, MB_MAGIC
je .multiboot_valid
LOG err_invalid_boot_magic, edi
jmp hang
.multiboot_valid:
LOG msg_hello_world
mov eax, [esi + mb_info.bootloader_name]
LOG msg_boot_info, eax
extern setup_gdt
call setup_gdt
;extern setup_pic
;call setup_pic
mov al, 0xff
out 0xa1, al
out 0x21, al
extern setup_idt
call setup_idt
push esi
extern setup_pmm
call setup_pmm
add esp, 4
test eax, 0
jz .mem_ok
LOG err_cannot_map_memory
jmp hang
.mem_ok:
LOG msg_pmm_initialized
extern setup_paging
call setup_paging
hang:
cli
hlt
jmp hang
section .rodata
msg_hello_world db "StupidOS v", STUPID_VERSION, " (built with ", __NASM_VER__, " on ", __DATE__, " ", __TIME__, ")", 0
msg_boot_info db "Bootloader: %s", 0
msg_pmm_initialized db "PMM initialized", 0
err_invalid_boot_magic db "[ERROR] Invalid boot magic (got: %x, expected: 0x2BADB002)", 0
err_cannot_map_memory db "[ERROR] Can't map memory", 0
file db __FILE__, 0

View file

@ -1,4 +1,4 @@
; file: msg_en ; file: msg_en.s
; English strings ; English strings
%include "i18n.inc" %include "i18n.inc"
@ -52,7 +52,7 @@ msg_en:
iend iend
msg_hello_world: msg_hello_world:
db "StupidOS v", STUPID_VERSION, " (built with ", NASM_VERSION, " on ", BUILD_DATE, ")", 0 db "StupidOS v", STUPID_VERSION, " (built with NASM v", __NASM_VER__, " on ", __DATE__, " ", __TIME__, ")", 0
msg_boot_info: msg_boot_info:
db "Bootloader: %s", 0 db "Bootloader: %s", 0
msg_pmm_initialized: msg_pmm_initialized:

View file

@ -2,25 +2,38 @@
; ;
[BITS 32] [BITS 32]
section .text section .text
global setup_idt
setup_idt:
%assign i 0
%rep 32
;; TODO: refactor
extern isr %+ i
mov eax, isr %+ i
; offset (low)
mov word [idt_entries + (i * 8)], ax
; segment selector (kernel code)
mov word [idt_entries + (i * 8) + 2], 0x08
idt_set_table:
push ebp
mov ebp, esp
mov ecx, [ebp + 8]
extern isr_list
mov eax, [isr_list + (ecx * 4)]
; offset (low)
mov word [idt_entries + (ecx * 8)], ax
; segment selector (kernel code)
mov word [idt_entries + (ecx * 8) + 2], 0x08
; zero (skip) ; zero (skip)
; attr: 1 (Present) 00 (DPL) 0 1 (D: 32bits) 110 ; attr: 1 (Present) 00 (DPL) 0 1 (D: 32bits) 110
mov byte [idt_entries + (i * 8) + 5], 0x8F mov byte [idt_entries + (ecx * 8) + 5], 0x8E
; offset (high) ; offset (high)
shr eax, 16 shr eax, 16
mov word [idt_entries + (i * 8) + 6], ax mov word [idt_entries + (ecx * 8) + 6], ax
leave
ret
global idt_setup
idt_setup:
%assign i 0
%rep 256
push dword i
call idt_set_table
add esp, 4
%assign i i+1 %assign i i+1
%endrep %endrep

View file

@ -4,22 +4,22 @@
%include "base.inc" %include "base.inc"
%macro ISR_NO_ERR 1 %macro ISR_NO_ERR 1
global isr%1
isr%1: isr%1:
xchg bx, bx
push dword 0 push dword 0
push dword %1 push dword %1
jmp isr_common jmp isr_common
%endmacro %endmacro
%macro ISR_ERR 1 %macro ISR_ERR 1
global isr%1
isr%1: isr%1:
xchg bx, bx
push dword %1 push dword %1
jmp isr_common jmp isr_common
%endmacro %endmacro
%macro ISR_ADDR 1
dd isr%1
%endmacro
section .text section .text
ISR_NO_ERR 0 ISR_NO_ERR 0
@ -55,6 +55,12 @@ ISR_NO_ERR 29
ISR_NO_ERR 30 ISR_NO_ERR 30
ISR_NO_ERR 31 ISR_NO_ERR 31
%assign i 32
%rep 224
ISR_NO_ERR i
%assign i i+1
%endrep
panic: panic:
LOG msg_interrupt LOG msg_interrupt
;htl ;htl
@ -71,6 +77,7 @@ isr_handler:
ret ret
isr_common: isr_common:
xchg bx, bx
push ds push ds
push es push es
push fs push fs
@ -83,8 +90,8 @@ isr_common:
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
;LOG msg_interrupt LOG msg_interrupt
call isr_handler ;call isr_handler
;extern pic_eoi ;extern pic_eoi
;call pic_eoi ;call pic_eoi
@ -97,30 +104,16 @@ isr_common:
iret iret
section .rodata section .data
global isr_list
isr_list:
%assign i 0
%rep 256
ISR_ADDR i
%assign i i+1
%endrep
msg_int_division_zero: db "Division by zero", 0x0 section .rodata
msg_int_debug: db "Debug", 0x0
msg_int_nmi: db "Non-maskable interrupt", 0x0
msg_int_breakpoint: db "Breakpoint", 0x0
msg_int_overflow: db "Overflow", 0x0
msg_int_range_exceeded: db "Bound range exceeded", 0x0
msg_int_invalid_opcode: db "Invalid Opcode", 0x0
msg_int_device_not_available: db "Device not available", 0x0
msg_int_double_fault: db "Double fault", 0x0
msg_int_coproc_segment_overrun: db "Coprocessor segment overrun", 0x0
msg_int_invalid_tss: db "Invalid TSS", 0x0
msg_int_seg_not_present: db "Segment not present", 0x0
msg_int_stack_segfault: db "Stack segment fault", 0x0
msg_int_gpf: db "General Protection Fault", 0x0
msg_int_page_fault: db "Page fault", 0x0
msg_int_reserved: db "Reserved", 0x0
msg_int_fp_exception: db "x87 Floating-Point Exception", 0x0
msg_int_align_check: db "Aligment check", 0x0
msg_int_machine_check: db "Machine check", 0x0
msg_int_simd_exception: db "SIMD Floating-Point exception", 0x0
msg_int_virt_exception: db "Virtualization exception", 0x0
msg_int_sec_exception: db "Security exception", 0x0
msg_interrupt db "interrupt", 0xA msg_interrupt db "interrupt", 0xA
db "edi: %x esi: %x ebp: %x esp: %x", 0xA db "edi: %x esi: %x ebp: %x esp: %x", 0xA

View file

@ -1,12 +1,30 @@
; File: kernel.s ; File: kernel.s
[BITS 32] [BITS 32]
%include "machdep.inc"
section .bss
align 16
stack_bottom:
resb 16384
global stack_top
stack_top:
section .text
; Function: kmain ; Function: kmain
.global kmain global kmain
kmain: kmain:
push ebp push ebp
mov ebp, esp mov ebp, esp
leave leave
ret ret
section .data
global machdep
machdep:
istruc machinfo
at machinfo.has_cpuid, db 0
at machinfo.has_pse, db 0
at machinfo.has_pae, db 0
iend

View file

@ -4,24 +4,33 @@ ENTRY(entry)
SECTIONS SECTIONS
{ {
. = 1M; . = 1M;
kernel_start = .; kernel_start = .;
.text : ALIGN(4) { .multiboot : {
KEEP(*(.multiboot)) KEEP(*(.multiboot.data))
KEEP(*(.multiboot.text))
}
. += 0xC0100000;
.text ALIGN(0x1000) : AT(ADDR(.text) - 0xC0000000) {
*(.text) *(.text)
} }
.rodata : ALIGN(4) { .rodata ALIGN(0x1000) : AT(ADDR(.rodata) - 0xC0000000) {
*(.rodata) *(.rodata)
} }
.data : ALIGN(4) { .data ALIGN(0x1000) : AT(ADDR(.data) - 0xC0000000) {
*(.data) *(.data)
} }
.bss : ALIGN(4) { .bss ALIGN(0x1000) : AT(ADDR(.bss) - 0xC0000000) {
bss_start = .;
*(COMMON) *(COMMON)
*(.bss) *(.bss)
bss_end = .;
} }
kernel_end = .; kernel_end = .;

5
kernel/machdep.inc Normal file
View file

@ -0,0 +1,5 @@
struc machinfo
.has_cpuid: resb 1
.has_pse: resb 1
.has_pae: resb 1
endstruc

View file

@ -6,29 +6,11 @@ PE_USERMODE equ 1 << 2
PE_ACCESSED equ 1 << 5 PE_ACCESSED equ 1 << 5
PE_DIRTY equ 1 << 6 PE_DIRTY equ 1 << 6
section .data section .bss
align 4096 align 4096
global page_directory
page_directory: page_directory:
times 1024 dd 0x00000000 resb 4096
global boot_page_table
section .text boot_page_table:
resb 4096
; Function: setup_paging
;
; in:
; none
;
; out:
; none
;
global setup_paging
setup_paging:
mov eax, page_directory
mov cr3, eax
mov eax, cr0
or eax, 1 << 31 ; enable paging
mov cr0, eax
ret

View file

@ -1,12 +1,32 @@
; file: pic.s ; file: pic.s
; ; <Datasheet at https://pdos.csail.mit.edu/6.828/2005/readings/hardware/8259A.pdf>
[BITS 32] [BITS 32]
PIC1_INT_START equ 0x20
PIC2_INT_START equ 0x28
PIC_INT_END equ PIC2_INT_START + 7
PIC1_CMD equ 0x20 PIC1_CMD equ 0x20
PIC1_DATA equ 0x21 PIC1_DATA equ 0x21
PIC2_CMD equ 0xA0 PIC2_CMD equ 0xA0
PIC2_DATA equ 0xA1 PIC2_DATA equ 0xA1
; Initialization Command Words (ICWs)
ICW1_INIT equ 1 << 4
ICW1_ICW4 equ 1 << 0
ICW1_SINGLE equ 1 << 1
ICW1_INTERVAL4 equ 1 << 2
ICW1_LVL_MODE equ 1 << 3
ICW4_8086_MODE equ 1 << 0
ICW4_AUTO_EOI equ 1 << 1
ICW4_BUF_SLAVE equ 1 << 3
ICW4_BUF_MASTER equ 1 << 3 | 1 << 2
ICW4_SFNM equ 1 << 4
; Operation Command Words (OWCs)
OCW2_EOI equ 1 << 5
section .text section .text
; Function: setup_pic ; Function: setup_pic
@ -17,15 +37,24 @@ section .text
; out: ; out:
; none ; none
; ;
global setup_pic global pic_setup
setup_pic: pic_setup:
mov al, 0x11 push ebp
mov ebp, esp
sub esp, 2
in al, PIC1_DATA
mov [ebp - 2], al
in al, PIC2_DATA
mov [ebp - 1], al
mov al, ICW1_INIT | ICW1_ICW4
out PIC1_CMD, al out PIC1_CMD, al
out PIC2_CMD, al out PIC2_CMD, al
mov al, 0x20 mov al, PIC1_INT_START
out PIC1_DATA, al out PIC1_DATA, al
mov al, 0x28 mov al, PIC2_INT_START
out PIC2_DATA, al out PIC2_DATA, al
mov al, 4 mov al, 4
@ -33,10 +62,16 @@ setup_pic:
mov al, 2 mov al, 2
out PIC2_DATA, al out PIC2_DATA, al
; mask all mov al, ICW4_8086_MODE
mov al, 0xFF
out PIC1_DATA, al out PIC1_DATA, al
out PIC2_DATA, al out PIC2_DATA, al
mov al, [ebp - 2]
out PIC1_DATA, al
mov al, [ebp - 1]
out PIC2_DATA, al
leave
ret ret
; Function: pic_eoi ; Function: pic_eoi
@ -49,7 +84,31 @@ setup_pic:
; ;
global pic_eoi global pic_eoi
pic_eoi: pic_eoi:
mov al, 0x20 push ebp
mov ebp, esp
mov al, OCW2_EOI
cmp byte [ebp + 8], PIC1_INT_START
jb .end
cmp byte [ebp + 8], PIC_INT_END
ja .end
cmp byte [ebp + 8], PIC2_INT_START
jb .pic1
out PIC2_CMD, al out PIC2_CMD, al
jmp .end
.pic1:
out PIC1_CMD, al out PIC1_CMD, al
.end:
leave
ret
; Function: pic_disable
global pic_disable
pic_disable:
mov al, 0xFF
out PIC1_DATA, al
out PIC2_DATA, al
ret ret

View file

@ -3,7 +3,7 @@
;; XXX: align address to page ;; XXX: align address to page
%include "base.inc" %include "base.inc"
%include "multiboot.inc" %include "sys/multiboot.inc"
extern kernel_size extern kernel_size
extern kernel_end extern kernel_end

13
kernel/sys/i386/cpuid.inc Normal file
View file

@ -0,0 +1,13 @@
;; File: cpuid.inc
CPUID_VENDORID equ 0x0
CPUID_GETFEATURES equ 0x1
CPUID_FEAT_EDX_FPU equ 1 << 0
CPUID_FEAT_EDX_VME equ 1 << 1
CPUID_FEAT_EDX_DE equ 1 << 2
CPUID_FEAT_EDX_PSE equ 1 << 3
CPUID_FEAT_EDX_TSC equ 1 << 4
CPUID_FEAT_EDX_MSR equ 1 << 5
CPUID_FEAT_EDX_PAE equ 1 << 6
CPUID_FEAT_EDX_MCE equ 1 << 7

40
kernel/sys/i386/mmu.inc Normal file
View file

@ -0,0 +1,40 @@
;; File: mmu.inc
%define V2P(addr) (addr - KERNBASE)
%define P2V(addr) (addr + KERNBASE)
%define P2PDE(addr) ((addr >> 22) & 0x3FF)
%define PDE2P(addr) (addr << 22)
%define P2PTE(addr) ((addr >> 12) & 0x3FF)
;; Defines: PDE
;; PTE_P - Present
PDE_P equ 1 << 0
PDE_W equ 1 << 1
PDE_U equ 1 << 2
PDE_PWT equ 1 << 3
PDE_PCD equ 1 << 4
PDE_A equ 1 << 5
PDE_D equ 1 << 6
PDE_PS equ 1 << 7
PDE_G equ 1 << 8
;; Defines: PTE
;; PTE_P - Present
;; PTE_W - Writable
;; PTE_U - User
;; PTE_PWT - Write-Through
;; PTE_PCD - Cache Disable
;; PTE_A - Accessed
;; PTE_D - Dirty
;; PTE_PAT -
;; PTE_G -
PTE_P equ 1 << 0
PTE_W equ 1 << 1
PTE_U equ 1 << 2
PTE_PWT equ 1 << 3
PTE_PCD equ 1 << 4
PTE_A equ 1 << 5
PTE_D equ 1 << 6
PTE_PAT equ 1 << 7
PTE_G equ 1 << 8

View file

@ -0,0 +1,126 @@
;; File: registers.inc
;; =========================================================================
;; Control Registers
;; =========================================================================
;; Defines: CR0
;; CR0_PE - Protected Mode Enable
;; CR0_MP - Monitor co-processor
;; CR0_EM - x87 FPU Emulation
;; CR0_TS - Task switched
;; CR0_ET - Extension type
;; CR0_NE - Numeric error
;; CR0_WP - Write protect
;; CR0_AM - Alignment mask
;; CR0_NW - Not-write through
;; CR0_CD - Cache disable
;; CR0_PG - Paging
CR0_PE equ 1 << 0
CR0_MP equ 1 << 1
CR0_EM equ 1 << 2
CR0_TS equ 1 << 3
CR0_ET equ 1 << 4
CR0_NE equ 1 << 5
CR0_WP equ 1 << 16
CR0_AM equ 1 << 18
CR0_NW equ 1 << 29
CR0_CD equ 1 << 30
CR0_PG equ 1 << 31
;; Defines: CR3
;; CR3_PWT - Page-level Write-Through
;; CR3_PCD - Page-level Cache Disable
CR3_PWT equ 1 << 3
CR3_PCD equ 1 << 4
;; Defines: CR4
;; CR4_VME - Virtual 8086 Mode Extensions
;; CR4_PVI - Protected-mode Virtual Interrupts
;; CR4_TSD - Time Stamp Disable
;; CR4_DE - Debugging Extensions
;; CR4_PSE - Page Size Extension
;; CR4_PAE - Physical Address Extension
;; CR4_MCE - Machine Check Exception
;; CR4_PGE - Page Global Enabled
;; CR4_PCE - Performance-Monitoring Counter enable
;; CR4_OSFXSR - Operating system support for FXSAVE and FXRSTOR
;; instructions
;; CR4_OSXMMEXCPT - Operating System Support for Unmasked SIMD
;; Floating-Point Excepions
;; CR4_UMIP - User-Mode Instruction Prevention
;; CR4_VMXE - Virtual Machine Extensions Enable
;; CR4_SMXE - Safer Mode Extensions Enable
;; CR4_FSGSBASE -
;; CR4_PCIDE - PCID Enable
;; CR4_OSXSSAVE - XSAVE and Processor Extended States Enable
;; CR4_SMEP - Supervisor Mode Execution Protection Enable
;; CR4_SMAP - Supervisor Mode Access Prevention Enable
;; CR4_PKE - Protection Key Enable
;; CR4_CET - Control-flow Enforcement Technology
;; CR4_PKS - Enable Protection Keys for Supervisor-Mode Pages
CR4_VME equ 1 << 0
CR4_PVI equ 1 << 1
CR4_TSD equ 1 << 2
CR4_DE equ 1 << 3
CR4_PSE equ 1 << 4
CR4_PAE equ 1 << 5
CR4_MCE equ 1 << 6
CR4_PGE equ 1 << 7
CR4_PCE equ 1 << 8
CR4_OSDXSR equ 1 << 9
CR4_OSXMMEXCPT equ 1 << 10
CR4_UMIP equ 1 << 11
CR4_VMXE equ 1 << 13
CR4_SMXE equ 1 << 14
CR4_FSGSBASE equ 1 << 16
CR4_PCIDE equ 1 << 17
CR4_OSXSAVE equ 1 << 18
CR4_SMEP equ 1 << 20
CR4_SMAP equ 1 << 21
CR4_PKE equ 1 << 22
CR4_CET equ 1 << 23
CR4_PKS equ 1 << 24
;; =========================================================================
;; eflags
;; =========================================================================
;; Defines: EFLAGS
;; EFLAGS_CF - Carry flag
;; EFLAGS_PF - Parity flag
;; EFLAGS_AF - Auxiliary flag
;; EFLAGS_ZF - Zero flag
;; EFLAGS_SF - Sign flag
;; EFLAGS_TF - Trap flag
;; EFLAGS_IF - Interrupt enable flag
;; EFLAGS_DF - Direction flag
;; EFLAGS_OF - Overflow flag
;; EFLAGS_IOPL1 - I/O privilege flag
;; EFLAGS_IOPL2 - I/O privilege flag
;; EFLAGS_NT - Nested task flag
;; EFLAGS_RF - Resume flag
;; EFLAGS_VM - Virtual 8086 mode flag
;; EFLAGS_AC - Alignment check
;; EFLAGS_VIF - Virtual Interrupt flag
;; EFLAGS_VIP - Virtual Interrupt pending
;; EFLAGS_ID - CPUID instruction available
EFLAGS_CF equ 1 << 0
EFLAGS_PF equ 1 << 2
EFLAGS_AF equ 1 << 4
EFLAGS_ZF equ 1 << 6
EFLAGS_SF equ 1 << 7
EFLAGS_TF equ 1 << 8
EFLAGS_IF equ 1 << 9
EFLAGS_DF equ 1 << 10
EFLAGS_OF equ 1 << 11
EFLAGS_IOPL1 equ 1 << 12
EFLAGS_IOPL2 equ 1 << 13
EFLAGS_NT equ 1 << 14
EFLAGS_RF equ 1 << 16
EFLAGS_VM equ 1 << 17
EFLAGS_AC equ 1 << 18
EFLAGS_VIF equ 1 << 19
EFLAGS_VIP equ 1 << 20
EFLAGS_ID equ 1 << 21

View file

@ -1,4 +1,6 @@
LIB = base LIB = base
SRCS = log.s SRCS = log.s
INCS = base.inc
include $(TOPDIR)/share/mk/stupid.lib.mk include $(TOPDIR)/share/mk/stupid.lib.mk
include $(TOPDIR)/share/mk/stupid.inc.mk

9
share/mk/stupid.inc.mk Normal file
View file

@ -0,0 +1,9 @@
include $(TOPDIR)/share/mk/stupid.own.mk
ifdef INCS
install::
$(INSTALL) -d $(DESTDIR)$(INCSDIR)
$(INSTALL) $^ $(DESTDIR)$(INCSDIR)
endif

View file

@ -4,7 +4,10 @@ include $(TOPDIR)/share/mk/stupid.own.mk
ifdef KERNEL ifdef KERNEL
ASFLAGS += -D__KERNEL__ -I$(TOPDIR)/kernel KERNBASE ?= 0xC0000000
ASFLAGS += -D__KERNEL__ -I$(TOPDIR)/kernel -DKERNBASE=$(KERNBASE) \
-I$(TOPDIR)/lib/base
OBJS = $(addsuffix .o, $(basename $(SRCS))) OBJS = $(addsuffix .o, $(basename $(SRCS)))
OBJS-dbg = $(addsuffix .dbg.o, $(basename $(SRCS))) OBJS-dbg = $(addsuffix .dbg.o, $(basename $(SRCS)))
@ -33,6 +36,10 @@ lib/%.dbg.o: ../lib/base/%.s
all: $(KERNEL) $(KERNEL)-dbg all: $(KERNEL) $(KERNEL)-dbg
install:: $(KERNEL) $(KERNEL)-dbg
$(INSTALL) -d $(DESTDIR)/
$(INSTALL) $^ $(DESTDIR)/
endif endif
include $(TOPDIR)/share/mk/stupid.clean.mk include $(TOPDIR)/share/mk/stupid.clean.mk

View file

@ -27,6 +27,10 @@ endif
all: lib$(LIB).a all: lib$(LIB).a
install:: lib$(LIB).a
$(INSTALL) -d $(DESTDIR)$(LIBDIR)
$(INSTALL) $< $(DESTDIR)$(LIBDIR)
endif endif
include $(TOPDIR)/share/mk/stupid.clean.mk include $(TOPDIR)/share/mk/stupid.clean.mk

View file

@ -16,13 +16,14 @@ LD = ld.lld
PLSCC = plsc PLSCC = plsc
OBJCOPY = llvm-objcopy OBJCOPY = llvm-objcopy
OBJDUMP = llvm-objdump OBJDUMP = llvm-objdump
INSTALL = install
MKCWD = mkdir -p $(@D) MKCWD = mkdir -p $(@D)
TARGETS = all clean install TARGETS = all clean install
.PHONY: $(TARGETS) .PHONY: $(TARGETS)
EXTRAFLAGS = -DSTUPID_VERSION="0.0" -D__STUPID__ EXTRAFLAGS = -DSTUPID_VERSION="\"0.0\"" -D__STUPID__
CFLAGS += -Wall -Werror -Wextra $(EXTRAFLAGS) CFLAGS += -Wall -Werror -Wextra $(EXTRAFLAGS)
CXXFLAGS += -Wall -Werror -Wextra $(EXTRAFLAGS) CXXFLAGS += -Wall -Werror -Wextra $(EXTRAFLAGS)

View file

@ -35,6 +35,10 @@ endif
all: $(PROG) all: $(PROG)
install:: $(PROG)
$(INSTALL) -d $(DESTDIR)$(LIBDIR)
$(INSTALL) $< $(DESTDIR)$(LIBDIR)
endif endif
include $(TOPDIR)/share/mk/stupid.clean.mk include $(TOPDIR)/share/mk/stupid.clean.mk

View file

@ -24,8 +24,8 @@ EOF
gen_iso_file() { gen_iso_file() {
mkdir -p "$2/boot/grub" mkdir -p "$2/boot/grub"
echo "$grub_config" > "$2/boot/grub/grub.cfg" echo "$grub_config" > "$2/boot/grub/grub.cfg"
sha256sum vmstupid > "$2/boot/hashfile" sha256sum "$2/vmstupid" > "$2/boot/hashfile"
sha256sum vmstupid-dbg >> "$2/boot/hashfile" sha256sum "$2/vmstupid-dbg" >> "$2/boot/hashfile"
grub-mkrescue -o $1 $2 grub-mkrescue -o $1 $2
} }