chore: rewrite from zero

This commit is contained in:
d0p1 🏳️‍⚧️ 2023-01-15 20:25:25 +01:00
parent 7455b79585
commit c9454eb5d3
19 changed files with 403 additions and 144 deletions

8
.editorconfig Normal file
View file

@ -0,0 +1,8 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = tab
indent_size = 4

3
.gitignore vendored
View file

@ -2,3 +2,6 @@
*.img
*.bin
*~
*.elf
*.dump

View file

@ -1,22 +1,41 @@
all: stupid.img kern.bin
.SUFFIXES:
.DELETE_ON_ERROR:
.DEFAULT_GOAL := all
stupid.img: floppy.bin kern.bin
mkdosfs -F 12 -C $@ 1440
dd status=noxfer conv=notrunc if=floppy.bin of=$@
mcopy -i $@ kern.bin ::kern.sys
AS = nasm
LD = ld.lld
OBJDUMP = llvm-objdump
RM = rm -f
floppy.bin: boot/floppy.s
nasm -fbin -o $@ $^
BIN_DIR = bin
DOC_DIR = doc
KERNEL_DIR = kernel
LIB_DIR = lib
TOOLS_DIR = tools
kern.bin: kern/kernel.s
nasm -fbin -o $@ $^
include $(TOOLS_DIR)/build.mk
ASFLAGS = -DSTUPID_VERSION=\"$(shell $(GIT-VERSION))\" -Ilib
GARBADGE = stupid.img
include $(KERNEL_DIR)/build.mk
all: stupid.img
stupid.img: $(KERNEL_BIN) $(KERNEL_DUMP)
#stupid.img: floppy.bin kern.bin
# mkdosfs -F 12 -C $@ 1440
# dd status=noxfer conv=notrunc if=floppy.bin of=$@
# mcopy -i $@ kern.bin ::kern.sys
%.dump: %.elf
$(OBJDUMP) -D $^ > $@
clean:
rm -rf floppy.bin kern.bin
$(RM) $(GARBADGE)
fclean: clean
rm -rf stupid.img
re: clean all
re: fclean all
.PHONY: all clean fclean re
.PHONY: all clean re

View file

@ -1,4 +1,4 @@
# StupidOS
16bit real mode Operating System in assembly
32-bit Operating System in assembly.

View file

@ -1,127 +0,0 @@
[ORG 0x7c00]
[BITS 16]
jmp short entry
nop
;; -----------------------------------------------------------
;; OEM & Bios Parameter Block
;; -----------------------------------------------------------
db "StupidOS"
bpb_bytes_per_sector dw 512 ; bytes per sector
bpb_sectors_per_cluster db 1 ; sector per cluster
bpb_reserved_sectors dw 1 ; reserved sector
bpb_number_of_fats db 2 ; number of FATs
bpb_root_entries dw 224 ; root entries
bpb_total_sectors dw 2880 ; total sector
bpb_media db 0xF0 ; media descriptor type
bpb_sectors_per_fat dw 9 ; sectors per FAT
bpb_sectors_per_track dw 18 ; sectors per track
bpb_heads_per_cylinder dw 2 ; heads per cylinder
bpb_hidden_sectors dd 0 ; hidden sectors
bpb_total_sector_big dd 0 ; total sector big
bpb_drive_number db 0 ; drive number
bpb_unused db 0 ; unused
bpb_signature db 0x29 ; drive signature (0x29 = floppy)
bpb_serial_number dd 0x00000000 ; serial number (ignore)
bpb_volume_label db 'STUPID DISK' ; volume label
bpb_filesystem db 'FAT12 ' ; filesystem type
;; -----------------------------------------------------------
;; entry
;; -----------------------------------------------------------
entry:
xor ax, ax
mov ds, ax
mov si, msg_boot
call boot_print
mov si, msg_copyright
call boot_print
reset_disk:
xor ah, ah
xor dl, dl
int 0x13
jc reset_disk
;; load kernel from FAT
;; store size of root dir in cx
xor cx, cx
xor dx, dx
mov ax, 0x0020
mul word [bpb_root_entries]
div word [bpb_bytes_per_sector]
xchg ax, cx
;; store loc of root directory in ax
mov al, byte [bpb_number_of_fats]
mul word [bpb_sectors_per_fat]
add ax, word [bpb_reserved_sectors]
;; mov word [datasec], ax
;; mov word [datasec], cx
mov bx, 0x0200
hang:
jmp hang
cli
hlt
;; -----------------------------------------------------------
;; Print string using bios interrupt
;; -----------------------------------------------------------
boot_print:
pusha
.loop:
lodsb
cmp al, 0
jz .end
mov ah, 0x0E ; bios print
mov bx, 0x07
int 0x10
jmp .loop
.end:
popa
ret
fatal_error:
pusha
mov cx, si
mov si, msg_error
call boot_print
mov si, cx
call boot_print
mov si, msg_press_any_key
call boot_print
xor ax, ax
int 0x16 ; wait keypressed
int 0x19 ; reboot
popa
ret
disk_read_sector:
pusha
popa
ret
;; -----------------------------------------------------------
;; Variables
;; -----------------------------------------------------------
msg_boot db "StupidOS - Bootloader", 13, 10, 0
msg_copyright db "Copyright (c) d0p1", 13, 10, 0
msg_press_any_key db "Press any key...", 13, 10, 0
msg_error db "[ERROR] ", 0
err_kern_not_found db "KERNEL.BIN not found...", 13, 10, 0
kernel_filename db "KERNEL BIN"
;; -----------------------------------------------------------
;; End
;; -----------------------------------------------------------
times 510-($-$$) db 0
db 0x55
db 0xAA

View file

@ -1 +0,0 @@
[BITS 16]

21
kernel/build.mk Normal file
View file

@ -0,0 +1,21 @@
include kernel/drivers/build.mk
KERNEL_SRCS = head.s gdt.s idt.s paging.s lib/log.s
KERNEL_OBJS = $(addprefix kernel/, $(KERNEL_SRCS:.s=.o) $(DRIVERS_OBJS))
KERNEL_BIN = stupid.elf
KERNEL_DUMP = $(KERNEL_BIN:.elf=.dump)
KERNEL_ASFLAGS = $(ASFLAGS) -D__KERNEL__
GARBADGE += $(KERNEL_OBJS) $(KERNEL_BIN) $(KERNEL_DUMP)
$(KERNEL_BIN): $(KERNEL_OBJS)
$(LD) -T $(KERNEL_DIR)/linker.ld -nostdlib -o $@ $^
kernel/lib/%.o: lib/base/%.s
mkdir -p $(@D)
$(AS) -felf -o $@ $< $(KERNEL_ASFLAGS)
kernel/%.o: kernel/%.s
$(AS) -felf -o $@ $< $(KERNEL_ASFLAGS)

2
kernel/drivers/build.mk Normal file
View file

@ -0,0 +1,2 @@
DRIVERS_SRCS = serial.s
DRIVERS_OBJS = $(addprefix drivers/, $(DRIVERS_SRCS:.s=.o))

48
kernel/drivers/serial.s Normal file
View file

@ -0,0 +1,48 @@
section .text
COM1 equ 0x3F8
COM2 equ 0x2F8
COM3 equ 0x3E8
COM4 equ 0x2E8
THR equ 0x0
RBR equ 0x0
IER equ 0x1
IIR equ 0x2
LCR equ 0x3
MCR equ 0x4
LSR equ 0x5
MSR equ 0x7
DLL equ 0x0
DLH equ 0x0
%macro COM_OUT 3
mov dx, %1+%2
mov al, %3
out dx, al
%endmacro
%macro COM_IN 2
mov dx, %1+%2
in al, dx
%endmacro
global serial_init
serial_init:
COM_OUT COM1, IER, 0x00
COM_OUT COM1, LCR, 0x80
COM_OUT COM1, DLH, 0x00
COM_OUT COM1, DLL, 0x0C
COM_OUT COM1, LCR, 0x03
ret
global serial_write
serial_write:
push ebp
mov ebp, esp
mov ecx, [ebp + 8]
COM_OUT COM1, THR, cl
pop ebp
ret

66
kernel/gdt.s Normal file
View file

@ -0,0 +1,66 @@
[BITS 32]
section .text
global setup_gdt
setup_gdt:
lgdt [gdt_ptr]
jmp 0x08:.flush_cs
.flush_cs:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
ret
section .data
gdt_ptr:
dw gdt_entries.end - gdt_entries - 1
dd gdt_entries
gdt_entries:
;; null descriptor
dw 0x0 ; limit
dw 0x0 ; base (low)
db 0x0 ; base (mid)
db 0x0 ; access
db 0x0 ; granularity
db 0x0 ; base (high)
;; kernel mode code segment
dw 0xFFFF
dw 0x00
db 0x00
db 0x9A
db 0xCF
db 0x00
;; kernel mode data segment
dw 0xFFFF
dw 0x00
db 0x00
db 0x92
db 0xCF
db 0x00
;; user mode code segment
dw 0xFFFF
dw 0x00
db 0x00
db 0xFA
db 0xCF
db 0x00
;; user mode data segment
dw 0xFFFF
dw 0x00
db 0x00
db 0xF2
db 0xCF
db 0x00
;; TSS
.end:

47
kernel/head.s Normal file
View file

@ -0,0 +1,47 @@
[BITS 32]
%include "base.inc"
MULTIBOOT_MAGIC equ 0x1BADB002
MULTIBOOT_ALIGN equ 1 << 0
MULTIBOOT_MEMINFO equ 1 << 1
MULTIBOOT_FLAGS equ MULTIBOOT_ALIGN | MULTIBOOT_MEMINFO
section .multiboot
align 4
dd MULTIBOOT_MAGIC
dd MULTIBOOT_FLAGS
dd -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)
section .bss
align 16
stack_bottom:
resb 16384
stack_top:
section .text
global entry
entry:
mov esp, stack_top
cli
extern serial_init
call serial_init
extern setup_gdt
call setup_gdt
extern setup_idt
call setup_idt
extern setup_paging
call setup_paging
LOG file
hang:
hlt
jmp hang
file db __FILE__, 0

16
kernel/idt.s Normal file
View file

@ -0,0 +1,16 @@
[BITS 32]
section .text
global setup_idt
setup_idt:
lidt [idt_ptr]
ret
section .data
idt_ptr:
dw idt_entries.end - idt_entries - 1
dd idt_entries
idt_entries:
times 256 dd 0x00000000, 0x00000000
.end:

2
kernel/kernel.s Normal file
View file

@ -0,0 +1,2 @@
[BITS 32]

25
kernel/linker.ld Normal file
View file

@ -0,0 +1,25 @@
OUTPUT_ARCH(i386)
ENTRY(entry)
SECTIONS
{
. = 1M;
.text : ALIGN(4) {
KEEP(*(.multiboot))
*(.text)
}
.rodata : ALIGN(4) {
*(.rodata)
}
.data : ALIGN(4) {
*(.data)
}
.bss : ALIGN(4) {
*(COMMON)
*(.bss)
}
}

20
kernel/paging.s Normal file
View file

@ -0,0 +1,20 @@
[BITS 32]
section .data
align 4096
page_directory:
times 1024 dd 0x00000002
section .text
global setup_paging
setup_paging:
mov eax, page_directory
mov cr3, eax
mov eax, cr0
or eax, 0x80000001
mov cr0, eax
ret

10
lib/base.inc Normal file
View file

@ -0,0 +1,10 @@
extern log_impl
%macro LOG 1
push %1
push file
call log_impl
add esp, 8
%endmacro

75
lib/base/log.s Normal file
View file

@ -0,0 +1,75 @@
[BITS 32]
%ifdef __KERNEL__
extern serial_write
%endif
section .text
putstr:
push ebp
mov ebp, esp
mov ebx, [ebp + 8]
.loop:
mov eax, [ebx]
cmp al, 0
je .end
push eax
%ifdef __KERNEL__
call serial_write
%else
%endif
add esp, 4
inc ebx
jmp .loop
.end:
pop ebp
ret
putuint:
push ebp
mov ebp, esp
mov ebx, [ebp + 8]
mov edx, [ebp + 12]
mov eax, buffer
push eax
call putstr
pop ebp
ret
global log_impl
log_impl:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
push eax
call putstr
add esp, 4
%ifdef __KERNEL__
push ':'
call serial_write
add esp, 4
%else
%endif
mov eax, [ebp + 12]
push eax
call putstr
add esp, 4
%ifdef __KERNEL__
mov al, 0xA
push eax
call serial_write
add esp, 4
%else
%endif
pop ebp
ret
digits db '0123456789ABCDEF'
buffer db '0000000000', 0

9
tools/build.mk Normal file
View file

@ -0,0 +1,9 @@
define TOOLS_TEMPLATE
$(1) = $$(addprefix $$(TOOLS_DIR)/, $$(shell echo -n $(1) | tr A-Z a-z))
endef
TOOLS = GIT-VERSION
$(foreach tool, $(TOOLS), $(eval $(call TOOLS_TEMPLATE, $(tool))))

16
tools/git-version Executable file
View file

@ -0,0 +1,16 @@
#!/bin/env sh
vers="$(git describe --abbrev=4 --match='v[0-9]*' HEAD 2>/dev/null)"
if [ ! -n "$vers" ]; then
vers="0.0"
fi
commit="$(git rev-parse --short HEAD)"
full_vers="${vers}-${commit}"
if [ -n "$(git status)" ]; then
full_vers="${full_vers}-dirty"
fi
echo -n "${full_vers}"