YEA
This commit is contained in:
parent
dab0070369
commit
bc32a1f2fa
|
@ -1 +0,0 @@
|
|||
.idea
|
34
kernel.c
34
kernel.c
|
@ -1,34 +0,0 @@
|
|||
void kprintstr(char* str);
|
||||
void khang();
|
||||
|
||||
/* HACK. kmain has to come first because of flat binary */
|
||||
|
||||
void kmain(void)
|
||||
{
|
||||
char* k_msg = "Hello world from 32-bit C kernel!";
|
||||
kprintstr(k_msg);
|
||||
khang();
|
||||
}
|
||||
|
||||
void kprintstr(char* str)
|
||||
{
|
||||
/* last line of 80x25 */
|
||||
char* ch = (char*)0xb8000 + 2 * 80 * 22;
|
||||
while(*str)
|
||||
{
|
||||
*ch = *str;
|
||||
ch++;
|
||||
*ch = 0xf; /* white character */
|
||||
ch++;
|
||||
str++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void khang()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
STAGE2_BASE equ 0x8000
|
||||
STAGE2_OFFSET equ 0x0
|
||||
STAGE2_FLAT equ (STAGE2_BASE * 0x10) + STAGE2_OFFSET
|
||||
|
||||
STAGE3_BASE equ 0x1000
|
||||
STAGE3_OFFSET equ 0
|
||||
STAGE3_FLAT equ (STAGE3_BASE * 0x10) + STAGE3_OFFSET
|
||||
|
||||
KERNEL_BASE equ 0x4000
|
||||
KERNEL_OFFSET equ 0
|
||||
KERNEL_FLAT equ (KERNEL_BASE * 0x10) + KERNEL_OFFSET
|
|
@ -0,0 +1,54 @@
|
|||
void kprintstr(char* str);
|
||||
void khang();
|
||||
void kdelay(int mills);
|
||||
/* HACK. kmain has to come first because of flat binary */
|
||||
|
||||
void kmain(void)
|
||||
{
|
||||
char* k_msg = "Hello world from 32-bit C kernel!"; /*33 characters*/
|
||||
kprintstr(k_msg);
|
||||
}
|
||||
|
||||
void kdelay(int millis)
|
||||
{
|
||||
for(int i = 0; i < millis; i++)
|
||||
{
|
||||
for(int j = 0; j < millis; j++)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void kprintstr(char* str)
|
||||
{
|
||||
/* 80x25 */
|
||||
char* ch = (char*)0xb8000 + 2 * 80 * 21;
|
||||
char color = 0xF;
|
||||
char swap[] = {'|','\\', '/', '\\', '/', '|', '|'};
|
||||
while(*str)
|
||||
{
|
||||
*ch = *str;
|
||||
ch++;
|
||||
*ch = color; /* white character */
|
||||
ch++;
|
||||
str++;
|
||||
}
|
||||
ch = (char*)0xb8000 + 2 * 80 * 22;
|
||||
while(1)
|
||||
{
|
||||
int i = 0;
|
||||
while(1)
|
||||
{
|
||||
/*display 10 characters doing*/
|
||||
for(int j = 0; j < 80 * 3; j++)
|
||||
{
|
||||
*(ch + j * 2) = swap[(i * 1337 + j * 33 ) % 3];
|
||||
*(ch + j * 2+ 1) = color;
|
||||
color = (color + 1) % 0xF;
|
||||
}
|
||||
kdelay(5000);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ ASM_FLAGS=-f bin -o
|
|||
CFLAGS=-ffreestanding -m32 -target i386-pc-none-elf -c -Wall -Wextra -Werror -mno-red-zone -std=c17 -o
|
||||
|
||||
STAGE1_TARGET=stage1.bin
|
||||
ASM_TARGET=stage2.bin stage1.bin
|
||||
ASM_TARGET=stage2.bin stage1.bin stage3.bin
|
||||
TARGET_DIR=out
|
||||
|
||||
all : createdir $(ASM_TARGET) kernel.bin image
|
|
@ -0,0 +1,122 @@
|
|||
; global position for vram
|
||||
vb_pos: dd 0
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
;print a 32-bit integer
|
||||
; input: push u32
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
print_u32:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
|
||||
; loop 4 times
|
||||
mov ebx, 8
|
||||
mov ecx, 32 - 4
|
||||
.lp:
|
||||
; eax = thing to print
|
||||
mov eax, dword [ebp + 2 * 4]
|
||||
shr eax, cl
|
||||
and eax, 0xF
|
||||
|
||||
call al_to_char
|
||||
call print_char
|
||||
|
||||
sub ecx, 4
|
||||
dec ebx
|
||||
test ebx, ebx
|
||||
jne .lp
|
||||
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
;print a char in
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
print_char:
|
||||
; input: al = char
|
||||
push edi
|
||||
push eax
|
||||
push esi
|
||||
push ecx
|
||||
|
||||
; esi points to current frame buffer
|
||||
mov esi, 0xb8000
|
||||
; edi points to offset
|
||||
mov edi, dword [vb_pos]
|
||||
|
||||
; handle return character
|
||||
cmp al, 0xA
|
||||
jne .char
|
||||
; round up to 80 * 2
|
||||
mov eax, edi
|
||||
add ax, 2 * 80 - 1
|
||||
mov cl, 2 * 80
|
||||
div cl
|
||||
mul cl
|
||||
mov edi, eax
|
||||
jmp .end
|
||||
.char:
|
||||
mov byte [esi + edi], al
|
||||
mov word [esi + edi + 1], 0xf
|
||||
add edi, 2
|
||||
|
||||
.end:
|
||||
mov dword [vb_pos], edi
|
||||
|
||||
pop ecx
|
||||
pop esi
|
||||
pop eax
|
||||
pop edi
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
;print a null-terminated string
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
print_str:
|
||||
;offset
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push esi
|
||||
push eax
|
||||
push edi
|
||||
|
||||
mov esi, dword [ebp + 2 * 4]
|
||||
|
||||
mov edi, 0xb8000
|
||||
|
||||
.loop_each_char:
|
||||
mov al, byte [esi]
|
||||
test al, al
|
||||
je .end
|
||||
call print_char
|
||||
inc esi
|
||||
jmp .loop_each_char
|
||||
|
||||
.end:
|
||||
pop edi
|
||||
pop eax
|
||||
pop esi
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
; helper function converting 4 bit val in al to its character
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
al_to_char:
|
||||
; no parameters
|
||||
cmp al,09h
|
||||
jna .l2
|
||||
add al,37h
|
||||
jmp .end
|
||||
.l2:
|
||||
add al,30h
|
||||
.end:
|
||||
ret
|
|
@ -1,4 +1,5 @@
|
|||
org 0x7c00
|
||||
%include "addr.inc"
|
||||
;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Constant definition
|
||||
;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -40,7 +41,6 @@ jmp $
|
|||
fn_stage2: db 'STAGE2 BIN',0
|
||||
|
||||
%include "fat12_drv.lib"
|
||||
%include "stage2.inc"
|
||||
|
||||
times 510-($ - $$) db 0
|
||||
dw 0xaa55
|
|
@ -1,4 +1,4 @@
|
|||
%include "stage2.inc"
|
||||
%include "addr.inc"
|
||||
|
||||
org STAGE2_OFFSET
|
||||
jmp start16
|
||||
|
@ -16,22 +16,36 @@ mov ax, 0xA
|
|||
call print_char
|
||||
%endmacro
|
||||
|
||||
%macro print_addr 2
|
||||
push %1
|
||||
call print_u16
|
||||
add sp, 2
|
||||
|
||||
mov ax, 0x3A ; colon
|
||||
call print_char
|
||||
|
||||
push %2
|
||||
call print_u16
|
||||
add sp, 2
|
||||
%endmacro
|
||||
|
||||
[section .data]
|
||||
[bits 16]
|
||||
fn_kernel: db 'KERNEL BIN',0
|
||||
fn_stage3: db 'STAGE3 BIN',0
|
||||
|
||||
msg_ok: db 'OK', 0
|
||||
msg_err: db 'ERR', 0
|
||||
msg_stage2_hello: db 'Stage2 loader at ', 0
|
||||
msg_det_mem_pre: db 'Detecting memory... ', 0
|
||||
msg_det_mem_title: db "Memory Information:", 0
|
||||
msg_det_mem_tbl_hdr: db 'Base Length Type',0 ; each field is of length 20
|
||||
msg_ok: db 'OK ', 0
|
||||
msg_err: db 'ERR ', 0
|
||||
|
||||
msg_stage2_hello: db 'Stage2 loader loaded at ', 0
|
||||
msg_det_mem: db 'Detecting memory... ', 0
|
||||
msg_det_mem_title: db "Memory Information: ", 0
|
||||
msg_det_mem_tbl_hdr: db 'Base Length Type ',0 ; each field is of length 20
|
||||
msg_det_mem_tbl_pad: db ' ',0 ; 4 x spaces
|
||||
|
||||
msg_ld_krnl_pre: db 'Loading kernel.bin... ', 0
|
||||
msg_ld_krnl_post: db 'kernel.bin loaded to ', 0
|
||||
|
||||
msg_pm_pre: db 'Initializing protected mode and jumping to kernel... ', 0
|
||||
msg_ld_stage3: db 'Loading stage3.bin... ', 0
|
||||
msg_ld_krnl: db 'Loading kernel.bin... ', 0
|
||||
msg_init_pm: db 'Initializing protected mode and jumping to stage3 loader... ', 0
|
||||
|
||||
|
||||
%include "fat12_hdr.inc"
|
||||
|
@ -52,37 +66,37 @@ mov al, 0x03
|
|||
int 0x10
|
||||
|
||||
print_msg msg_stage2_hello
|
||||
|
||||
push word STAGE2_BASE
|
||||
call print_u16
|
||||
add sp, 2
|
||||
|
||||
mov ax, 0x3A ; colon
|
||||
call print_char
|
||||
|
||||
push word STAGE2_OFFSET
|
||||
call print_u16
|
||||
add sp, 2
|
||||
|
||||
print_addr STAGE2_BASE, STAGE2_OFFSET
|
||||
print_rtn
|
||||
print_msg msg_det_mem_pre
|
||||
|
||||
print_msg msg_det_mem
|
||||
call detect_mem
|
||||
|
||||
cmp ax, 1
|
||||
je .err
|
||||
|
||||
print_msg msg_ok
|
||||
print_rtn
|
||||
|
||||
print_msg msg_det_mem_title
|
||||
print_rtn
|
||||
|
||||
call print_mem_layout
|
||||
|
||||
print_rtn
|
||||
|
||||
print_msg msg_ld_krnl_pre
|
||||
print_msg msg_ld_stage3
|
||||
push word fn_stage3
|
||||
push word STAGE3_OFFSET
|
||||
push word STAGE3_BASE
|
||||
call fat12_read_file
|
||||
add esp, 6
|
||||
cmp ax, 1
|
||||
je .err
|
||||
|
||||
print_msg msg_ok
|
||||
print_addr STAGE3_BASE, STAGE3_OFFSET
|
||||
print_rtn
|
||||
|
||||
print_msg msg_ld_krnl
|
||||
push word fn_kernel
|
||||
push word KERNEL_OFFSET
|
||||
push word KERNEL_BASE
|
||||
|
@ -92,25 +106,10 @@ cmp ax, 1
|
|||
je .err
|
||||
|
||||
print_msg msg_ok
|
||||
print_addr KERNEL_BASE, KERNEL_OFFSET
|
||||
print_rtn
|
||||
|
||||
print_msg msg_ld_krnl_post
|
||||
|
||||
push word KERNEL_BASE
|
||||
call print_u16
|
||||
add sp, 2
|
||||
|
||||
mov ax, 0x3A ; colon
|
||||
call print_char
|
||||
|
||||
push word KERNEL_OFFSET
|
||||
call print_u16
|
||||
add sp, 2
|
||||
|
||||
print_rtn
|
||||
|
||||
print_msg msg_pm_pre
|
||||
|
||||
print_msg msg_init_pm
|
||||
|
||||
;load gdt
|
||||
lgdt [gdtr32]
|
||||
|
@ -125,6 +124,10 @@ mov eax,cr0
|
|||
or eax,1
|
||||
mov cr0,eax
|
||||
|
||||
; pass the frame buffer
|
||||
xor ebx, ebx
|
||||
mov bx, word [vb_pos]
|
||||
|
||||
jmp dword gdt32.sel_code:(STAGE2_FLAT + start32)
|
||||
|
||||
start16.err:
|
||||
|
@ -235,23 +238,20 @@ ret
|
|||
[section .text]
|
||||
[bits 32]
|
||||
start32:
|
||||
; ebx holds -> vram_buffer
|
||||
mov ax,gdt32.sel_data
|
||||
mov ss,ax
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov gs,ax
|
||||
; adjust
|
||||
|
||||
mov esp, STAGE2_FLAT + stack32
|
||||
|
||||
;Jump to The Kernel
|
||||
mov eax, KERNEL_FLAT
|
||||
;Jump to stage 3
|
||||
mov eax, STAGE3_FLAT
|
||||
jmp eax
|
||||
|
||||
[section .data]
|
||||
[bits 32]
|
||||
times 1024 db 0
|
||||
stack32:
|
||||
|
||||
gdt32:
|
||||
dd 0
|
||||
dd 0
|
|
@ -0,0 +1,141 @@
|
|||
org 0x10000 ; 64k this is terrible but IDC
|
||||
%include "addr.inc"
|
||||
%macro print_msg 1
|
||||
mov eax, %1
|
||||
push eax
|
||||
call print_str
|
||||
add esp, 4
|
||||
%endmacro
|
||||
|
||||
%macro print_rtn 0
|
||||
mov eax, 0xA
|
||||
call print_char
|
||||
%endmacro
|
||||
|
||||
%macro print_addr 2
|
||||
push %1
|
||||
call print_u32
|
||||
add esp, 4
|
||||
|
||||
mov eax, 0x3A ; colon
|
||||
call print_char
|
||||
|
||||
push %2
|
||||
call print_u32
|
||||
add esp, 4
|
||||
%endmacro
|
||||
|
||||
[SECTION .text]
|
||||
[BITS 32]
|
||||
jmp start
|
||||
%include "print32.lib"
|
||||
start:
|
||||
mov dword [vb_pos], ebx ; ebx holds framebuffer pointer
|
||||
|
||||
print_msg msg_ok
|
||||
print_rtn
|
||||
|
||||
print_msg msg_switch_gdt_pre
|
||||
; switch stack and GDT
|
||||
lgdt [gdtr32]
|
||||
jmp dword gdt32.sel_code:.reload
|
||||
.reload:
|
||||
mov ax, gdt32.sel_data
|
||||
mov ds, ax
|
||||
mov ss, ax
|
||||
mov es, ax
|
||||
mov gs, ax
|
||||
mov fs, ax
|
||||
mov esp, stack
|
||||
|
||||
print_msg msg_ok
|
||||
print_rtn
|
||||
|
||||
print_msg msg_init_idt
|
||||
|
||||
; write offset to idt
|
||||
mov eax, dummy_handler
|
||||
mov word [idt32], ax
|
||||
mov cl, 16
|
||||
shr eax, cl
|
||||
mov word [idt32 + 6], ax
|
||||
|
||||
lidt [idtr32]
|
||||
print_msg msg_ok
|
||||
print_rtn
|
||||
|
||||
print_msg msg_test_div
|
||||
xor ax, ax
|
||||
div ax
|
||||
next_op:
|
||||
print_msg msg_ok
|
||||
print_rtn
|
||||
|
||||
print_msg msg_init_krnl
|
||||
mov eax, KERNEL_FLAT
|
||||
jmp eax
|
||||
|
||||
err:
|
||||
print_msg msg_err
|
||||
jmp $
|
||||
|
||||
|
||||
dummy_handler:
|
||||
print_msg msg_div
|
||||
call print_u32 ; top of stack is the address
|
||||
print_msg msg_space
|
||||
mov dword [esp], next_op ; overwrite return address
|
||||
iretd
|
||||
|
||||
[SECTION .data]
|
||||
[BITS 32]
|
||||
msg_div: db '#DIV at ', 0
|
||||
msg_space: db ' ', 0
|
||||
msg_ok: db 'OK ', 0
|
||||
msg_err: db 'ERR ', 0
|
||||
msg_switch_gdt_pre: db 'Reloading GDT and stack... ', 0
|
||||
msg_init_idt: db 'Initializing IDT... ', 0
|
||||
msg_test_div: db 'Testing #DIV exception... ', 0
|
||||
msg_init_krnl: db 'Jumping to kernel... ', 0
|
||||
|
||||
align 4096
|
||||
times 4096 db 0
|
||||
stack:
|
||||
|
||||
align 16
|
||||
idt32:
|
||||
dw 0 ; offset low 16 bits
|
||||
dw gdt32.sel_code ; selector
|
||||
db 0
|
||||
db 0b10001111 ; Present | DPL 0 | Trap gate
|
||||
dw 0
|
||||
.size equ $ - idt32
|
||||
|
||||
idtr32:
|
||||
dw idt32.size - 1
|
||||
dd idt32
|
||||
|
||||
align 16
|
||||
gdt32:
|
||||
dd 0
|
||||
dd 0
|
||||
.sel_code: equ $ - gdt32
|
||||
dw 0xFFFF ; LIMIT = 0xFFFF
|
||||
dw 0 ; BASE LOW = 0
|
||||
db 0 ; BASE MID = 0
|
||||
db 10011010b; PRESENT | RW | EXE
|
||||
db 11001111b; Granularity = 4k | 32 bits
|
||||
db 0 ; BASE_HIGH = 0
|
||||
.sel_data: equ $ - gdt32
|
||||
dw 0xFFFF ; LIMIT = 0xFFFF
|
||||
dw 0 ; BASE LOW = 0
|
||||
db 0 ; BASE MID = 0
|
||||
db 10010010b; PRESENT | RW | EXE
|
||||
db 11001111b; Granularity = 4k | 32 bits
|
||||
db 0 ; BASE_HIGH = 0
|
||||
.size: equ $ - gdt32
|
||||
|
||||
align 16
|
||||
gdtr32:
|
||||
dw gdt32.size - 1
|
||||
dd gdt32
|
|
@ -1,7 +0,0 @@
|
|||
STAGE2_BASE equ 0x8000
|
||||
STAGE2_OFFSET equ 0x0
|
||||
STAGE2_FLAT equ (STAGE2_BASE * 0x10) + STAGE2_OFFSET
|
||||
|
||||
KERNEL_BASE equ 0x4000
|
||||
KERNEL_OFFSET equ 0x0
|
||||
KERNEL_FLAT equ (KERNEL_BASE * 0x10) + KERNEL_OFFSET
|
Loading…
Reference in New Issue