Compare commits

..

10 commits

Author SHA1 Message Date
d0p1 🏳️‍⚧️ 7f88017ed7 feat(bootload): load next stage and preload kernel from FAT 2024-02-08 14:58:18 +01:00
d0p1 🏳️‍⚧️ d94d9fb5bb chore: misc files 2024-02-06 18:27:51 +01:00
d0p1 🏳️‍⚧️ 670a7f3bb4 feat: stage0 of a tiny boot loader 2024-02-06 15:20:27 +01:00
d0p1 🏳️‍⚧️ 3fddd705f8 refactor: switch from NASM to FASM 2024-02-04 20:50:36 +01:00
d0p1 🏳️‍⚧️ 32f1956ca2 refactor: rework IDT and GDT 2023-07-13 16:00:20 +02:00
d0p1 🏳️‍⚧️ 08a7d5c975 docs: documente ISA/AT buses I/O Port map 2023-07-13 13:47:23 +02:00
d0p1 🏳️‍⚧️ a9fec6e18c feat: setup paging and map kernel to higher half
Kernel is now at 0xC0100000, but still we use 4MiB pages, instruction like 'invlpg' which are invalid for cpu prior to 486, and we don't ensure multiboot structures are mapped. Still lot of work
2023-07-12 13:31:08 +02:00
imgbot[bot] fd991daeed
chore(imgbot): optimize images (#1)
*Total -- 127.36kb -> 97.71kb (23.28%)

/docs/img/logo.png -- 5.75kb -> 4.29kb (25.33%)
/docs/img/pmap_bootstrap.png -- 121.61kb -> 93.42kb (23.18%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
Co-authored-by: ImgBotApp <ImgBotHelp@gmail.com>
2023-07-12 11:40:19 +02:00
d0p1 🏳️‍⚧️ 72f4ef1f00 docs: documents memory management 2023-07-12 11:33:44 +02:00
d0p1 🏳️‍⚧️ 5cccfa22d4 feat(kernel): WIP higher half kernel 2023-07-02 16:52:25 +02:00
59 changed files with 1036 additions and 1703 deletions

View file

@ -11,7 +11,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install build-essential llvm lld nasm mtools
sudo apt-get install build-essential fasm mtools
- name: Build
run: |
make

3
.gitignore vendored
View file

@ -23,3 +23,6 @@ a.out
*.old
/bx_enh_dbg.ini
bochsrc.bxrc
/tmp
*.tar.gz
*.sys

View file

@ -1,13 +1,43 @@
.DEFAULT_GOAL := all
TOPDIR := $(CURDIR)
export TOPDIR
SUBDIR := thirdparty lib bin kernel
.PHONY: docs
docs:
-mkdir -p docs/html
naturaldocs -p docs/config -img docs/img -xi tmp -i . -o HTML docs/html
cp docs/img/favicon.ico docs/html/
include $(TOPDIR)/share/mk/stupid.subdir.mk
TOPDIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
SYSROOTDIR := $(TOPDIR)/sysroot
TOOLSDIR := $(TOPDIR)/tools
RM = echo
SUBDIRS := boot kernel lib bin
TARGET = stupid.tar.gz floppy_boot.img
ifneq ($(OS),Windows_NT)
TARGET += stupid.iso
endif
.PHONY: all
all: $(TARGET)
GOAL:=install
clean: GOAL:=clean
.PHONY: $(SUBDIRS)
$(SUBDIRS):
@echo "📁 $@"
DESTDIR=$(SYSROOTDIR) $(MAKE) -C $@ $(GOAL)
.PHONY: stupid.iso
stupid.iso: $(SUBDIRS)
$(TOPDIR)/tools/create-iso $@ sysroot
.PHONY: stupid.tar.gz
stupid.tar.gz: $(SUBDIRS)
tar -czvf $@ sysroot
.PHONY: floppy_boot.img
floppy_boot.img:
dd if=/dev/zero of=$@ bs=512 count=1440
mformat -C -f 1440 -i $@
dd if=boot/bootsector.bin of=$@ conv=notrunc
mcopy -i $@ boot/stpdboot.sys ::/STPDBOOT.SYS
mcopy -i $@ kernel/vmstupid ::/VMSTUPID.SYS
.PHONY: clean
clean: $(SUBDIRS)
$(RM) $(TARGET) $(SYSROOTDIR)

View file

@ -3,18 +3,22 @@
# StupidOS
[Website](https://stupidos.d0p1.eu)
![GitHub](https://img.shields.io/github/license/d0p1s4m4/stupidos?logoColor=white&style=flat-square)
![GitHub issues](https://img.shields.io/github/issues/d0p1s4m4/stupidos?style=flat-square)
[![GitHub](https://img.shields.io/github/license/d0p1s4m4/stupidos?logoColor=white&style=flat-square)](LICENSE)
[![GitHub issues](https://img.shields.io/github/issues/d0p1s4m4/stupidos?style=flat-square)](https://github.com/d0p1s4m4/StupidOS/issues)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/d0p1s4m4?style=flat-square)](https://github.com/sponsors/d0p1s4m4)
</div>
32-bit Operating System in assembly.
32-bit Operating System written in x86 assembly.
## Philosophy
Nowaday, all Software are overengineered bloatware. So let's try to keep things simple, stupid.
## Building
```
$ sudo apt install build-essential llvm lld nasm mtools
$ sudo apt install build-essential fasm mtools
$ git clone git@github.com:d0p1s4m4/StupidOS.git
$ cd StupidOS
$ make
@ -24,7 +28,7 @@ Pretty easy, isn't it?
## License
<img src="https://opensource.org/files/OSI_Approved_License.png" align="right" height="128px" alt="OSI Approved License">
<img src="https://opensource.org/wp-content/themes/osi/assets/img/osi-badge-light.svg" align="right" height="128px" alt="OSI Approved License">
StupidOS is licensed under the 3-Clause BSD License.

View file

@ -1,3 +1,11 @@
NOSUBDIR := 1
SUBDIRS = cmd
include $(TOPDIR)/share/mk/stupid.subdir.mk
TOPGOALS = all clean install
.PHONY: $(SUBDIRS)
$(SUBDIRS):
@echo "📁 bin/$@"
DESTDIR=$(DESTDIR)/bin $(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: $(TOPGOALS)
$(TOPGOALS): $(SUBDIRS)

5
bin/cmd/Makefile Normal file
View file

@ -0,0 +1,5 @@
all:
clean:
install:

6
bin/cmd/builtins.inc Normal file
View file

@ -0,0 +1,6 @@
builtins:
db 2, 'cd'
db 1, '.'
db 3, 'set'
db 5, 'unset'
db 4, 'exit'

8
bin/cmd/cmd.asm Normal file
View file

@ -0,0 +1,8 @@
format ELF
entry start
include 'builtins.inc'
start:
int 0x2A

29
boot/Makefile Normal file
View file

@ -0,0 +1,29 @@
AS = fasm
RM = rm
TARGET = bootsector.bin stpdboot.sys
STAGE0_SRCS = boot0.asm \
const.inc \
fat12.inc
STAGE1_SRCS = boot1.asm \
const.inc \
a20.inc
.PHONY: all
all: $(TARGET)
bootsector.bin: $(STAGE0_SRCS)
$(AS) boot0.asm $@
stpdboot.sys: $(STAGE1_SRCS)
$(AS) boot1.asm $@
.PHONY: clean
clean:
$(RM) $(TARGET)
.PHONY: install
install: $(TARGET)
@ mkdir -p $(DESTDIR)

2
boot/README.org Normal file
View file

@ -0,0 +1,2 @@
#+TITLE: StupidOS Bootloader

171
boot/a20.inc Normal file
View file

@ -0,0 +1,171 @@
; copy/pasted from https://wiki.osdev.org/A20_Line
; .... sorry I was lazy :x
a20_get_state:
pushf
push si
push di
push ds
push es
cli
xor ax, ax
mov ds, ax
mov si, 0x500
not ax
mov es, ax
mov di, 0x0510
mov al, [ds:si] ; save old values
mov byte [.BufferBelowMB], al
mov al, [es:di]
mov byte [.BufferOverMB], al
mov ah, 1 ; check byte [0x00100500] == byte [0x0500]
mov byte [ds:si], 0
mov byte [es:di], 1
mov al, [ds:si]
cmp al, [es:di]
jne .exit
dec ah
.exit:
mov al, [.BufferBelowMB]
mov [ds:si], al
mov al, [.BufferOverMB]
mov [es:di], al
shr ax, 8
sti
pop es
pop ds
pop di
pop si
popf
ret
.BufferBelowMB: db 0
.BufferOverMB db 0
a20_query_support:
push bx
clc
mov ax, 0x2403
int 0x15
jc .error
test ah, ah
jnz .error
mov ax, bx
pop bx
ret
.error:
stc
pop bx
ret
a20_enable_keyboard_controller:
cli
call .wait_io1
mov al, 0xad
out 0x64, al
call .wait_io1
mov al, 0xd0
out 0x64, al
call .wait_io2
in al, 0x60
push eax
call .wait_io1
mov al, 0xd1
out 0x64, al
call .wait_io1
pop eax
or al, 2
out 0x60, al
call .wait_io1
mov al, 0xae
out 0x64, al
call .wait_io1
sti
ret
.wait_io1:
in al, 0x64
test al, 2
jnz .wait_io1
ret
.wait_io2:
in al, 0x64
test al, 1
jz .wait_io2
ret
; out:
; cf - set on error
a20_enable:
clc ; clear cf
pusha
mov bh, 0 ; clear bh
call a20_get_state
jc .fast_gate
test ax, ax
jnz .done
call a20_query_support
mov bl, al
test bl, 1 ; enable A20 using keyboard controller
jnz .keybord_controller
test bl, 2 ; enable A20 using fast A20 gate
jnz .fast_gate
.bios_int:
mov ax, 0x2401
int 0x15
jc .fast_gate
test ah, ah
jnz .failed
call a20_get_state
test ax, ax
jnz .done
.fast_gate:
in al, 0x92
test al, 2
jnz .done
or al, 2
and al, 0xfe
out 0x92, al
call a20_get_state
test ax, ax
jnz .done
test bh, bh ; test if there was an attempt using the keyboard controller
jnz .failed
.keybord_controller:
call a20_enable_keyboard_controller
call a20_get_state
test ax, ax
jnz .done
mov bh, 1 ; flag enable attempt with keyboard controller
test bl, 2
jnz .fast_gate
jmp .failed
.failed:
stc
.done:
popa
ret

120
boot/boot0.asm Normal file
View file

@ -0,0 +1,120 @@
INCLUDE 'const.inc'
ORG STAGE0_BASE
USE16
jmp short _start
nop
; Boot Record
OEM_identifier db 'STUPID '
bytes_per_sector dw 512
sectors_per_cluster db 1
reserved_sectors dw 1
FAT_count db 2
root_dir_entries dw 224
total_sectors dw 2880
media_desc_type db 0xF0
sectors_per_FAT dw 9
sectors_per_track dw 18
heads_per_cylinder dw 2
hidden_sectors dd 0
large_sector_count dd 0
; Extended Boot Record
drive_number db 0x0
reserved db 0x0
signature db 0x29 ; 0x28 or 0x29
volume_id dd 0xB00B135 ; hope mine will grow :'(
volume_label db 'Stupid Boot'
system_id db 'FAT12 '
_start:
cli
cld
jmp 0x0:.canonicalize_cs
.canonicalize_cs:
xor ax, ax
mov ds, ax
mov ss, ax
mov es, ax
mov sp, 0x7c00
mov [drive_number], dl
; reset floppy disk
@@:
mov dl, [drive_number]
xor ah, ah
int 0x13
jc @b
call fat_load_root
; search in root directory
mov si, kernel_file
call fat_search_root
jc .error_not_found
mov [kernel_start], ax
mov si, stage1_file
call fat_search_root
jc .error_not_found
mov [stage1_start], ax
; load fat
xor ax, ax
mov al, [FAT_count]
mul word [sectors_per_FAT]
mov cx, ax
mov ax, [reserved_sectors]
xor bx, bx
call disk_read_sectors
; preload kernel
mov ax, KERNEL_PRELOAD/0x10
mov es, ax
mov ax, [kernel_start]
xor bx, bx
call fat_load_binary
; load stage 2
mov ax, STAGE1_BASE/0x10
mov es, ax
mov ax, [stage1_start]
xor bx, bx
call fat_load_binary
jmp 0x0:STAGE1_BASE
.error_not_found:
push si
mov si, msg_error
call bios_print
pop si
call bios_print
mov si, msg_not_found
call bios_print
hlt
jmp $
INCLUDE "utils.inc"
INCLUDE "fat12.inc"
msg_error db "ERROR: ", 0
msg_not_found db " not found", CR, LF, 0
kernel_file db "VMSTUPIDSYS", 0
stage1_file db "STPDBOOTSYS", 0
kernel_start dw 0x0
stage1_start dw 0x0
rb 0x7C00+512-2-$
db 0x55, 0xAA

28
boot/boot1.asm Normal file
View file

@ -0,0 +1,28 @@
INCLUDE 'const.inc'
ORG STAGE1_BASE
USE16
stage2:
push cs
pop ds
mov si, msg_stage2
call bios_print
call a20_enable
jc .error_a20
jmp .hang
.error_a20:
mov si, msg_error_a20
call bios_print
.hang:
hlt
jmp $
INCLUDE 'a20.inc'
INCLUDE 'utils.inc'
msg_stage2 db "StupidOS Bootloader (Stage 1)", 0x0D, 0x0A, 0
msg_error_a20 db "ERROR: can't enable a20 line", 0x0D, 0x0A, 0

9
boot/const.inc Normal file
View file

@ -0,0 +1,9 @@
CR = 0x0D
LF = 0x0A
; -------- Address ----------
STAGE0_BASE = 0x7C00
STAGE1_BASE = 0x1000
DISK_BUFFER = 0x8000
KERNEL_PRELOAD = 0xF000
STACK_TOP = 0x7000

181
boot/fat12.inc Normal file
View file

@ -0,0 +1,181 @@
ATTR_READ_ONLY = 0x01
ATTR_HIDDEN = 0x02
ATTR_SYSTEM = 0x04
ATTR_VOLUME_ID = 0x08
ATTR_DIRECTORY = 0x10
ATTR_ARCHIVE = 0x20
struc fat_entry
{
.name db 8 dup ?
.ext db 3 dup ?
.attrs db ?
.reserved dw ?
.creation_time dw ?
.creation_date dw ?
.access_date dw ?
.reserved2 dw ?
.mod_time dw ?
.mod_date dw ?
.start dw ?
.size dd ?
}
virtual at di
fat_entry fat_entry
end virtual
; CHS to LBA
; LBA = (C * HPC + H) * SPT + (S - 1)
;;; Read sectors from disk to buffer
;;;
;;; @param AX LBA starting sector
;;; @param CX sector count
;;; @param ES:BX buffer
;;;
disk_read_sectors:
; https://en.wikipedia.org/wiki/Logical_block_addressing
; convert LBA to CHS
; HPC = Head per Cluster
; SPT = Sector per Track
; S = (LBA % SPT) + 1
push ax
push bx
push cx
xor dx, dx
div word [sectors_per_track]
inc dx
mov [S], dx
; H = (LBA / SPT) % HPC
; C = LBA / (HPC * SPT)
xor dx, dx
div word [heads_per_cylinder]
mov [C], ax
mov [H], dx
; read sectors
mov ah, 0x2
mov al, 0x1
mov ch, byte [C]
mov cl, byte [S]
mov dh, byte [H]
mov dl, [drive_number]
int 0x13
jc @f
pop cx
pop bx
pop ax
add bx, word [bytes_per_sector]
inc ax
loop disk_read_sectors
ret
@@:
mov si, msg_error_sector
call bios_print
ret
C dw 0x00
H dw 0x00
S dw 0x00
fat_load_root:
mov ax, DISK_BUFFER/0x10
mov es, ax
; load root directory
mov ax, [sectors_per_FAT]
xor cx, cx
mov cl, [FAT_count]
mul cx
add ax, [reserved_sectors]
push ax
mov bx, [bytes_per_sector]
mov cl, 0x5
shr bx, cl
mov ax, [root_dir_entries]
xor dx, dx
div bx
mov cx, ax
pop ax
mov [data_start], ax
add [data_start], cx
xor bx, bx
call disk_read_sectors
ret
;; @param SI filename to search
fat_search_root:
mov cx, [root_dir_entries]
mov di, 0x0
@@:
push si
push cx
mov cx, 0xB ; name(8) + ext(3)
push di
rep cmpsb
pop di
pop cx
pop si
je .file_found
add di, 0x20
loop @b
; set carry if not found
stc
ret
.file_found:
mov ax, [es:fat_entry.start]
clc
ret
;;; @param AX cluster
;;; @param ES:BX buffer
fat_load_binary:
push ax
sub ax, 0x2
xor cx, cx
mov cl, [sectors_per_cluster]
mul cx
add ax, [data_start]
xor cx, cx
mov cl, [sectors_per_cluster]
call disk_read_sectors
pop ax
mov cx, ax
mov dx, ax
shr dx, 0x1
add cx, dx
push bx
mov bx, DISK_BUFFER
add bx, cx
mov dx, [bx]
pop bx
test ax, 0x1
jnz .odd_cluster
.even_cluster:
and dx, 0xFFF
jmp .end
.odd_cluster:
shr dx, 0x4
.end:
mov ax, dx
cmp dx, 0xFF0
jb fat_load_binary
ret
msg_error_sector db "ERROR: reading sector", CR, LF, 0
data_start dw 0x0

9
boot/utils.inc Normal file
View file

@ -0,0 +1,9 @@
bios_print:
lodsb
or al, al
jz @f
mov ah, 0x0E
int 0x10
jmp bios_print
@@:
ret

View file

@ -41,33 +41,65 @@ Timestamp: Updated yyyy/mm/dd
File: Introduction (docs/intro.txt)
Link: Source Code (https://github.com/d0p1s4m4/StupidOS)
File: Coding Style (docs/coding-style.txt)
File: Building (building.txt)
File: FAQ (docs/faq.txt)
Group: Kernel {
File: head.s (kernel/head.s)
File: gdt.s (kernel/gdt.s)
File: idt.s (kernel/idt.s)
File: multiboot.inc (kernel/multiboot.inc)
File: pic.s (kernel/pic.s)
File: paging.s (no auto-title, kernel/paging.s)
File: Introduction (kernel/intro.txt)
Group: Driver {
Group: boot {
File: serial.s (no auto-title, kernel/drivers/serial.s)
} # Group: Driver
File: gdt.s (kernel/boot/gdt.s)
File: head.s (kernel/boot/head.s)
File: idt.s (kernel/boot/idt.s)
} # Group: boot
File: kernel.s (kernel/kernel.s)
File: msg_en (kernel/i18n/msg_en.s)
File: pic.s (kernel/pic.s)
Group: dev {
Group: AT {
File: IBM PC/AT (kernel/dev/at/intro.txt)
File: cmos.s (kernel/dev/at/cmos.s)
File: pit.s (kernel/dev/at/pit.s)
File: serial.s (kernel/dev/at/serial.s)
} # Group: AT
} # Group: dev
Group: i18n {
File: msg_en.s (kernel/i18n/msg_en.s)
} # Group: i18n
File: pmm.s (kernel/pmm.s)
Group: sys {
File: multiboot.inc (kernel/sys/multiboot.inc)
Group: i386 {
File: cpu.inc (kernel/sys/i386/cpu.inc)
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
File: vm.inc (kernel/vm/vm.inc)
File: pmap.s (kernel/vm/pmap.s)
} # Group: Kernel
Group: Lib {
File: base.inc (lib/base.inc)
Group: Base {
File: base.inc (lib/base/base.inc)
File: log.s (lib/base/log.s)
} # Group: Base

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -0,0 +1,89 @@
---
title: pmap_bootstrap
---
flowchart TD
R_BEGIN("Begin")
R_GETMMAP["Get Memory Map entry"]
R_MMAP_LAST{"Last Item ?"}
R_END("End")
subgraph "entry to pmap_block"
C_BEGIN("Begin Proc")
C_IS_FREE{"Is
entry free?"}
C_END("End Proc")
C_OVERLAP_KERNEL{"entry
overlap
kernel?"}
C_REMOVE_KRESERVED["Remove Kernel
Memory from entry"]
C_MEMORY_SIZE_EXCEED{"Is entry size
larger than
0x0x7f80000 ?"}
C_MEMORY_SPLIT["Split entry"]
C_MEMORY_LAST["Is last ?"]
C_BEGIN-->C_IS_FREE
C_IS_FREE--No-->C_END
C_IS_FREE--Yes-->C_OVERLAP_KERNEL
C_OVERLAP_KERNEL--Yes-->C_REMOVE_KRESERVED
C_REMOVE_KRESERVED-->C_MEMORY_SIZE_EXCEED
C_OVERLAP_KERNEL--No-->C_MEMORY_SIZE_EXCEED
C_MEMORY_SIZE_EXCEED--Yes-->C_MEMORY_SPLIT
C_MEMORY_SPLIT-->C_MEMORY_LAST
C_MEMORY_LAST--Yes-->C_END
end
subgraph "create & store pmap_block"
D_BEGIN("Begin Proc")
D_BOOSTRAP_EXIST{"Bootstrap
pmap_block
exist?"}
D_SETUP_BOOTSTRAP["Setup bootstrap pmap"]
D_END("End Proc")
D_SET_HEAD_BOOTSTRAP["Set bootstrap as Head"]
D_SEARCH_FREE_PAGE["Search free page in Head->bitmap"]
D_FREE_PAGE_FOUND{"Free Page found ?"}
D_HEAD_NEXT_NULL{"Head->next == NULL?"}
D_HEAD_NEXT["Set Head to Head->next"]
D_CREATE_PMAP["Create new pmap_block
in free page"]
D_APPEND_PMAP["Append pmap_block
at end of
linked list"]
D_BEGIN-->D_BOOSTRAP_EXIST
D_BOOSTRAP_EXIST--No-->D_SETUP_BOOTSTRAP
D_SETUP_BOOTSTRAP-->D_END
D_BOOSTRAP_EXIST--Yes-->D_SET_HEAD_BOOTSTRAP
D_SET_HEAD_BOOTSTRAP-->D_SEARCH_FREE_PAGE
D_SEARCH_FREE_PAGE-->D_FREE_PAGE_FOUND
D_FREE_PAGE_FOUND--No-->D_HEAD_NEXT_NULL
D_HEAD_NEXT_NULL--No-->D_HEAD_NEXT
D_HEAD_NEXT-->D_SEARCH_FREE_PAGE
D_FREE_PAGE_FOUND--Yes-->D_CREATE_PMAP
D_CREATE_PMAP-->D_APPEND_PMAP
D_APPEND_PMAP-->D_END
end
R_BEGIN-->R_GETMMAP
R_GETMMAP-->R_MMAP_LAST
R_MMAP_LAST--Yes-->R_END
R_MMAP_LAST--No-->C_BEGIN
C_MEMORY_SIZE_EXCEED--No-->D_BEGIN
D_END--Try get next-->C_MEMORY_LAST
C_MEMORY_LAST--No-->D_BEGIN
C_END--Try get next entry-->R_MMAP_LAST
style R_BEGIN fill:#6CA300
style R_END fill:#A30000
style C_BEGIN fill:#6CA300
style C_END fill:#A30000
style D_BEGIN fill:#6CA300
style D_END fill:#A30000

BIN
docs/img/pmap_bootstrap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View file

@ -2,17 +2,14 @@ File: Introduction
About: StupidOS
(see logo.png)
(see logo.png)
Donate:
- <Liberapay at https://liberapay.com/d0p1/>
- <Github Sponsors at https://github.com/sponsors/d0p1s4m4>
- Monero: 85cm3SuAs98dcqXcdiyCNz6hkb5fKwHbtJYr8cyFdAGWKgj8rG3kPENNv1BXVp2HsiaC8otTzxxaEEuUVZQFxrSr7eBY2uw
- Zcash: zs1sqsdn4acrqygvupmhwl5vvzcdjk6fd4p6n3k4nzdey0huq7cwkl2ca7dru8alhhtan47wjes0x9
- Bitcoin: bc1qhpxa0hgj0mjstttkjgg6ees9dj5kadty04kgpp
- Oxen: LDrNKN6iXh98zUZbwa9iGmeuiWbrzU2WTKWwcwMYFSeCj2QACxfyFXNVQyN8QBe61bFgqtykTYpgcaWvf2C1K77KMQ82DaC
- Gridcoin: S8tw8EWXQ6p529kLEniCePceNAFTyc3GKM
About: License

View file

@ -1,5 +1,27 @@
KERNEL = vmstupid
SRCS = head.s gdt.s pic.s isr.s idt.s pmm.s paging.s \
lib/log.s drivers/serial.s
AS = fasm
RM = rm -f
INSTALL = install
include $(TOPDIR)/share/mk/stupid.kernel.mk
KERNEL = vmstupid
SRCS = kernel.asm \
const.inc \
boot/multiboot.inc \
boot/boot.inc \
mm/mm.inc
.PHONY: all
all: $(KERNEL)
$(KERNEL): $(SRCS)
$(AS) kernel.asm $@
.PHONY: clean
clean:
$(RM) $(KERNEL)
.PHONY: install
install: $(KERNEL)
@ mkdir -p $(DESTDIR)
install $< $(DESTDIR)
.PHONY: all clean

View file

@ -1,4 +0,0 @@
struc console
.init:
endstruc

35
kernel/boot/boot.inc Normal file
View file

@ -0,0 +1,35 @@
ORG 0x100000
ALIGN 4
USE32
INCLUDE 'boot/multiboot.inc'
INCLUDE 'const.inc'
mb_header MultibootHeader MB_FLAGS, mb_header, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_DEPTH
_start:
cli
cmp eax, MULTIBOOT_MAGIC
jne hang
; iterate over memory
;
;
xor esi, esi
mov edi, kernel_page_table - KBASE
mov ecx, kernel_page_directory - KBASE
mov cr3, ecx
mov ecx, cr0
hang:
hlt
jmp $-1
; SEGMENT readable writable
boot_struct dd 0x0

106
kernel/boot/multiboot.inc Normal file
View file

@ -0,0 +1,106 @@
MULTIBOOT_HDR_MAGIC = 0x1BADB002
MULTIBOOT_MAGIC = 0x2BADB002
MULTIBOOT_HDR_ALIGN = 0x1
MULTIBOOT_HDR_MEMINFO = 0x2
MULTIBOOT_HDR_VIDEO = 0x4
struc MultibootHeader flags,addr,width,height,depth
{
.magic dd MULTIBOOT_HDR_MAGIC
.flags dd flags
.checksum dd -(MULTIBOOT_HDR_MAGIC + flags)
; address fields (we'll just skip them)
.header_addr dd addr
.load_addr dd 0x100000
.load_end_addr dd _edata - KBASE
.bss_end_addr dd _end - KBASE
.entry_addr dd _start
; Video mode
.mode_type dd 0x0
.width dd width
.height dd height
.depth dd depth
}
struc MultibootData
{
.flags dd ?
; if flags[0] is set
.mem_lower dd ?
.mem_upper dd ?
; if flags[1] is set
.boot_device dd ?
; if flags[2] is set
.cmdline dd ?
; if flags[3] is set
.mods_count dd ?
.mods_addr dd ?
; if flags[4] is set
.syms dd 4 dup ?
; if flags[6] is set
.mmap_length dd ?
.mmap_addr dd ?
; if flags[7] is set
.drives_length dd ?
.drives_addr dd ?
; if flags[8] is set
.config_table dd ?
; if flags[9] is set
.bootloader_name dd ?
; if flags[10] is set
.apm_table dd ?
; if flags[11] is set
.vbe_control_info dd ?
.vbe_mode_info dd ?
.vbe_mode dw ?
.vbe_if_seg dw ?
.vbe_if_off dw ?
.vbe_if_length dw ?
; if flags[12] is set
.fb_addr dq ?
.fb_pitch dd ?
.fb_width dd ?
.fb_height dd ?
.fb_bpp db ?
.fb_type db ?
.fb_misc dw 3 dup ?
}
MULTIBOOT_DATA_MEM = 0x0001
MULTIBOOT_DATA_BOOTDEV = 0x0002
MULTIBOOT_DATA_CMDLINE = 0x0004
MULTIBOOT_DATA_MODULES = 0x0008
MULTIBOOT_DATA_MMAP = 0x0040
MULTIBOOT_DATA_DRIVES = 0x0080
MULTIBOOT_DATA_BOOTLOADER_NAME = 0x0200
MULTIBOOT_DATA_VBE = 0x0800
MULTIBOOT_DATA_FB = 0x1000
struc MultibootMMap
{
.size dd ?
.addr dq ?
.length dq ?
.type dd ?
}
MULTIBOOT_MEMORY_AVAILABLE = 0x1
MULTIBOOT_MEMORY_RESERVED = 0x2
MULTIBOOT_MEMORY_ACPI = 0x3
MULTIBOOT_MEMORY_NVS = 0x4
MULTIBOOT_MEMORY_BADPARAM = 0x5

53
kernel/const.inc Normal file
View file

@ -0,0 +1,53 @@
KBASE = 0xC0000000
PSIZE = 0x1000
; --------- VERSION -------------
VERSION_MAJOR = 1
VERSION_MINOR = 0
; --------- BOOT PARAMS ---------
MB_FLAGS = MULTIBOOT_HDR_ALIGN or MULTIBOOT_HDR_MEMINFO or MULTIBOOT_HDR_VIDEO
VIDEO_WIDTH = 1024
VIDEO_HEIGHT = 768
VIDEO_DEPTH = 32
; --------- Registers ------------
CR0_PE = 0x00000001
CR0_MP = 0x00000002
CR0_EM = 0x00000004
CR0_TS = 0x00000008
CR0_ET = 0x00000010
CR0_NE = 0x00000020
CR0_WP = 0x00010000
CR0_AM = 0x00040000
CR0_NW = 0x20000000
CR0_CD = 0x40000000
CR0_PG = 0x80000000
CR3_PWT = 0x08
CR3_PCD = 0x10
CR4_VME = 0x0000001
CR4_PVI = 0x0000002
CR4_TSD = 0x0000004
CR4_DE = 0x0000008
CR4_PSE = 0x0000010
CR4_PAE = 0x0000020
CR4_MCE = 0x0000040
CR4_PGE = 0x0000080
CR4_PCE = 0x0000100
CR4_OSDXSR = 0x0000200
CR4_OSXMMEXCPT = 0x0000400
CR4_UMIP = 0x0000800
CR4_VMXE = 0x0002000
CR4_SMXE = 0x0004000
CR4_FSGSBASE = 0x0010000
CR4_PCIDE = 0x0020000
CR4_OSXSAVE = 0x0040000
CR4_SMEP = 0x0100000
CR4_SMAP = 0x0200000
CR4_PKE = 0x0400000
CR4_CET = 0x0800000
CR4_PKS = 0x1000000

View file

@ -1,51 +0,0 @@
struc tss
.link: resd 1
endstruc
struc gdt_entry
.limit_low: resw 1
.base_low: resw 1
.base_mid: resb 1
.access: resb 1
.flags: resb 1
.base_high: resb 1
endstruc
struc idt_entry
.limit_low: resw 1
.selector: resw 1
.zero: resb 1
.attr: resb 1
.base_high: resw 1
endstruc
struc intframe
;; registers
.edi: resd 1
.esi: resd 1
.ebp: resd 1
.esp: resd 1
.ebx: resd 1
.edx: resd 1
.ecx: resd 1
.eax: resd 1
;;
.gs: resd 1
.fs: resd 1
.es: resd 1
.ds: resd 1
.intno: resd 1
;; by x86 hardware
.err: resd 1
.eip: resd 1
.cs: resd 1
.eflags: resd 1
;; crossring
.useresp: resd 1
.ss: resd 1
endstruc

View file

@ -1,64 +0,0 @@
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
; Function: serial_init
;
; in:
; none
;
; out:
; none
;
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
; Function: serial_write
;
; in:
; none
;
; out:
; none
;
global serial_write
serial_write:
push ebp
mov ebp, esp
mov ecx, [ebp + 8]
COM_OUT COM1, THR, cl
leave
ret

View file

@ -1,14 +0,0 @@
struc superblock
.devid: resd 1
.size: resd 1
.ninode: resd 1
.fs_type: resd 1
endstruc
struc inode
.devid: resd 1
.size: resd 1
.inode: resd 1s
.access: resd 1
endstruc

View file

@ -1,76 +0,0 @@
; file: gdt.s
;
;
[BITS 32]
section .text
; Function: setup_gdt
;
; in:
; none
;
; out:
; none
;
global setup_gdt
setup_gdt:
lgdt [gdt_ptr]
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x08:.flush_cs
.flush_cs:
mov ax, 0x10 ; data segment
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
dd 0x0
dd 0x0
;; kernel mode code segment
dw 0xFFFF ; Limit
dw 0x0000 ; Base (low)
db 0x00 ; Base (mid)
db 0x9A ; Access: 1 (P) 0 (DPL), 1 (S), 1010 (Type)
db 0xCF ; Granularity: 1 (G), 1 (D/B), 0 (AVL), Limit
db 0x00 ; Base (high)
;; kernel mode data segment
dw 0xFFFF
dw 0x0000
db 0x00
db 0x92
db 0xCF
db 0x00
;; user mode code segment
dw 0xFFFF
dw 0x0000
db 0x00
db 0xFA
db 0xCF
db 0x00
;; user mode data segment
dw 0xFFFF
dw 0x0000
db 0x00
db 0xF2
db 0xCF
db 0x00
;; TSS
.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,10 +0,0 @@
struc lang_entry
.code: resb 2
.data: resd 1
.next: resd 1
endstruc
struc msg_table
.hello_world: resd 1
.cpu_exceptions: resd 32
endstruc

View file

@ -1,102 +0,0 @@
; file: msg_en
; English strings
%include "i18n.inc"
.section rodata
global lang_en
lang_en:
istruc lang_entry
at lang_entry.code: db "en"
at lang_entry.data: dd msg_en
at lang_entry.next: dd 0
iend
msg_en:
istruc msg_table
at msg_table.hello_world: dd msg_hello_world
at msg_table.cpu_exceptions:
dd msg_int_division_zero
dd msg_int_debug
dd msg_int_nmi
dd msg_int_breakpoint
dd msg_int_overflow
dd msg_int_range_exceeded
dd msg_int_invalid_opcode
dd msg_int_device_not_available
dd msg_int_double_fault
dd msg_int_coproc_segment_overrun
dd msg_int_invalid_tss
dd msg_int_seg_not_present
dd msg_int_stack_segfault
dd msg_int_gpf
dd msg_int_page_fault
dd msg_int_reserved
dd msg_int_fp_exception
dd msg_int_align_check
dd msg_int_machine_check
dd msg_int_simd_exception
dd msg_int_virt_exception
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
dd msg_int_reserved
iend
msg_hello_world:
db "StupidOS v", STUPID_VERSION, " (built with ", NASM_VERSION, " on ", BUILD_DATE, ")", 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
warn_no_mmap:
db "[WARN] mmap flag not set", 0
msg_mmap_entry:
db "Memory Map Entry:", 0xA
db 0x9, "Address: (hi): %x (lo): %x", 0xA
db 0x9, "Length: (hi): %x (lo): %x", 0xA
db 0x9, "Type: %x", 0
msg_mem_block:
db "Free Memory:", 0xA
db 0x9, "Address: %x", 0xA
db 0x9, "Length: %x", 0
msg_max_mem:
db "Max memory: %x", 0
msg_bitmap_stored_at:
db "Bitmap stored at: %x", 0
msg_int_division_zero: db "Division by zero", 0x0
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

View file

@ -1,46 +0,0 @@
; file: idt.s
;
[BITS 32]
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
; zero (skip)
; attr: 1 (Present) 00 (DPL) 0 1 (D: 32bits) 110
mov byte [idt_entries + (i * 8) + 5], 0x8F
; offset (high)
shr eax, 16
mov word [idt_entries + (i * 8) + 6], ax
%assign i i+1
%endrep
lidt [idt_ptr]
sti
ret
section .data
align 8
idt_ptr:
dw idt_entries.end-idt_entries-1
dd idt_entries
; variable: idt_entries
align 8
idt_entries:
times 256 dd 0x00000000, 0x00000000
;; dw offset (low)
;; dw segment selector
;; db zero
;; db attr | P | DPL | 0 D 1 1 0 |
;; dw offset (high)
.end:

View file

@ -1,131 +0,0 @@
[BITS 32]
%include "cpu.inc"
%include "base.inc"
%macro ISR_NO_ERR 1
global isr%1
isr%1:
xchg bx, bx
push dword 0
push dword %1
jmp isr_common
%endmacro
%macro ISR_ERR 1
global isr%1
isr%1:
xchg bx, bx
push dword %1
jmp isr_common
%endmacro
section .text
ISR_NO_ERR 0
ISR_NO_ERR 1
ISR_NO_ERR 2
ISR_NO_ERR 3
ISR_NO_ERR 4
ISR_NO_ERR 5
ISR_NO_ERR 6
ISR_NO_ERR 7
ISR_ERR 8
ISR_NO_ERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NO_ERR 15
ISR_NO_ERR 16
ISR_NO_ERR 17
ISR_NO_ERR 18
ISR_NO_ERR 19
ISR_NO_ERR 20
ISR_NO_ERR 21
ISR_NO_ERR 22
ISR_NO_ERR 23
ISR_NO_ERR 24
ISR_NO_ERR 25
ISR_NO_ERR 26
ISR_NO_ERR 27
ISR_NO_ERR 28
ISR_NO_ERR 29
ISR_NO_ERR 30
ISR_NO_ERR 31
panic:
LOG msg_interrupt
;htl
;jmp panic
ret
isr_handler:
push ebp
mov ebp, esp
.end:
leave
ret
isr_common:
push ds
push es
push fs
push gs
pusha
mov ax, 0x10 ; data segment
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;LOG msg_interrupt
call isr_handler
;extern pic_eoi
;call pic_eoi
popa
pop gs
pop fs
pop es
pop ds
add esp, 8 ; int no & error code
iret
section .rodata
msg_int_division_zero: db "Division by zero", 0x0
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
db "edi: %x esi: %x ebp: %x esp: %x", 0xA
db "ebx: %x edx: %x ecx: %x eax: %x", 0xA
db "gs: %x fs: %x es: %x ds: %x", 0xA
db "int: %x err: %x eip: %x cs: %x", 0xA
db "flg: %x usp: %x ss: %x", 0x0
file db __FILE__, 0

15
kernel/kernel.asm Normal file
View file

@ -0,0 +1,15 @@
INCLUDE 'boot/boot.inc'
ORG $ + KBASE
INCLUDE 'mm/mm.inc'
kmain:
nop
_edata:
; BSS
rb 0x4000
_end:

View file

@ -1,12 +0,0 @@
; File: kernel.s
[BITS 32]
; Function: kmain
.global kmain
kmain:
push ebp
mov ebp, esp
leave
ret

View file

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

11
kernel/mm/mm.inc Normal file
View file

@ -0,0 +1,11 @@
free_block_head dd 0x0
mm_init:
ret
kernel_page_directory:
dd 0x1000 dup 0x0
kernel_page_table:
dd 0x1000 dup 0x0

7
kernel/mm/stats.inc Normal file
View file

@ -0,0 +1,7 @@
struc VMStat
{
total_page dd 0
free_pages dd 0
used_pages dd 0
}

View file

@ -1,133 +0,0 @@
; File: multiboot.inc
; Define: MB_HDR_MAGIC
; Multiboot Header Magic
MB_HDR_MAGIC equ 0x1BADB002
; Define: MB_MAGIC
; Multiboot Magic passed by the bootloader.
MB_MAGIC equ 0x2BADB002
; Structure: mb_header
;
; .magic - todo
; .flags - See <flags>
; .checksum - todo
; .aout_kludge - todo
; .mode_type - todo
; .width - todo
; .height - todo
; .depth - todo
struc mb_header
.magic: resd 1
.flags: resd 1
.checksum: resd 1
.aout_kludge: resd 5
.mode_type: resd 1
.width: resd 1
.height: resd 1
.depth: resd 1
endstruc
; Defines: flags
;
; MB_HDR_ALIGN - todo
; MB_HDR_MEMINFO - <mb_info.mem_lower>
; MB_HDR_VIDEO - todo
MB_HDR_ALIGN equ 1 << 0
MB_HDR_MEMINFO equ 1 << 1
MB_HDR_VIDEO equ 1 << 2
; Structure: mb_info
;
; Fields:
; .flags - See <flags>
; .mem_lower - todo
; .mem_upper - todo
; .boot_device - todo
; .
struc mb_info
;; flags
.flags: resd 1
;; flags[0] is set
.mem_lower: resd 1
.mem_upper: resd 1
;; flags[1] is set
.boot_device: resd 1
;; flags[2] is set
.cmdline: resd 1
;; flags[3] is set
.mods_count: resd 1
.mods_addr: resd 1
;; flags[4] || flags[4] is set
.syms: resd 4
;; flags[6] is set
.mmap_length: resd 1
; <mb_info.mmap_length>
; see <mb_mmap>
.mmap_addr: resd 1
;; flags[7] is set
.drives_length: resd 1
.drives_addr: resd 1
;; flags[8] is set
.config_table: resd 1
;; flags[9] is set
.bootloader_name: resd 1
;; flags[10] is set
.apm_table: resd 1
;;
.vbe_control_info: resd 1
.vbe_mode_info: resd 1
.vbe_mode: resw 1
.vbe_interface_seg: resw 1
.vbe_interface_off: resw 1
.vbe_interface_len: resw 1
.framebuffer_addr: resq 1
.framebuffer_pitch: resd 1
.framebuffer_width: resd 1
.framebuffer_height: resd 1
.framebuffer_bpp: resb 1
.framebuffer_type: resb 1
.framebuffer_misc: resw 3
endstruc
; Defines: flags
;
; MB_INFO_MEM - todo
; MB_INFO_BOOTDEV - todo
MB_INFO_MEM equ 1 << 0
MB_INFO_BOOTDEV equ 1 << 1
; Structure: mb_mmap
struc mb_mmap
.size: resd 1
.addr: resq 1
.length: resq 1
.type: resd 1
endstruc
; Defines: types
;
; MB_MEMORY_AVAILABLE - 1
; MB_MEMORY_RESERVED - 2
; MB_MEMORY_ACPI - 3
; MB_MEMORY_NVS - 4
; MB_MEMORY_BADRAM - 5
%define MB_MEMORY_AVAILABLE 1
%define MB_MEMORY_RESERVED 2
%define MB_MEMORY_ACPI 3
%define MB_MEMORY_NVS 4
%define MB_MEMORY_BADRAM 5

View file

@ -1,34 +0,0 @@
[BITS 32]
PE_PRESENT equ 1 << 0
PE_WRITABLE equ 1 << 1
PE_USERMODE equ 1 << 2
PE_ACCESSED equ 1 << 5
PE_DIRTY equ 1 << 6
section .data
align 4096
page_directory:
times 1024 dd 0x00000000
section .text
; 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,55 +0,0 @@
; file: pic.s
;
[BITS 32]
PIC1_CMD equ 0x20
PIC1_DATA equ 0x21
PIC2_CMD equ 0xA0
PIC2_DATA equ 0xA1
section .text
; Function: setup_pic
;
; in:
; none
;
; out:
; none
;
global setup_pic
setup_pic:
mov al, 0x11
out PIC1_CMD, al
out PIC2_CMD, al
mov al, 0x20
out PIC1_DATA, al
mov al, 0x28
out PIC2_DATA, al
mov al, 4
out PIC1_DATA, al
mov al, 2
out PIC2_DATA, al
; mask all
mov al, 0xFF
out PIC1_DATA, al
out PIC2_DATA, al
ret
; Function: pic_eoi
;
; in:
; none
;
; out:
; none
;
global pic_eoi
pic_eoi:
mov al, 0x20
out PIC2_CMD, al
out PIC1_CMD, al
ret

View file

@ -1,387 +0,0 @@
; File: pmm.s
[BITS 32]
;; XXX: align address to page
%include "base.inc"
%include "multiboot.inc"
extern kernel_size
extern kernel_end
struc bitmap
.length: resd 1
.addr: resd 1
endstruc
section .text
bitmap_count_free_page:
push ebp
mov ebp, esp
push edi
push esi
push ebx
mov edi, [bitmap_info + bitmap.addr]
xor ebx, ebx
.loop:
inc edi
inc ebx
cmp ebx, [bitmap_info]
jb .loop
.end:
pop ebx
pop esi
pop edi
leave
ret
bitmap_mark:
push ebp
mov ebp, esp
push edi
push esi
mov edi, 1
mov eax, [ebp + 8]
and eax, 0x7 ; eax % 8
mov ecx, eax
shl edi, cl
mov eax, [ebp + 8]
shr eax, 0x3 ; eax / 8
mov esi, [bitmap_info + bitmap.addr]
add esi, eax
mov dl, byte [esi]
mov ecx, [ebp + 12]
test ecx, ecx
jz .clear
or edx, edi ; set bit
jmp .end
.clear:
not edi
and edx, edi ; clear bit
.end:
mov byte [esi], dl
pop esi
pop edi
leave
ret
init_bitmap:
push ebp
mov ebp, esp
push edi
mov ecx, [bitmap_info]
mov edi, [bitmap_info + bitmap.addr]
rep stosb
xchg bx, bx
pop edi
leave
ret
bitmap_mark_range_free:
push ebp
mov ebp, esp
push edi
push esi
push ebx
mov edi, [ebp + 8] ; start address
mov esi, [ebp + 12] ; length
xor ebx, ebx ; counter (I know I SHOUD use 'ecx' as counter
; but since the ABI state it's not preserved
; accross function call)
push dword 0 ; bitmap_mark(addr, 0) == clear
.loop:
cmp ebx, esi
jnb .end_loop
add edi, ebx
jc .end_loop ; exit on overflow
push edi
call bitmap_mark
add esp, 4
add ebx, 0x1000 ; add page size
jmp .loop
.end_loop:
add esp, 4
pop ebx
pop esi
pop edi
leave
ret
setup_pmm_mmap:
push ebp
mov ebp, esp
sub esp, 4
push edi
push esi
push ebx
mov edi, [ebp + 8] ; mb_mmap struct addr
mov esi, [ebp + 12] ; mmap length
xor ebx, ebx ; pass
mov [ebp - 4], ebx ; set max addr to 0
.loop:
;; TODO: PAE stuff
;; skip address > 32bit
mov eax, [edi + mb_mmap.addr + 4]
and eax, eax
jnz .next
mov eax, [edi + mb_mmap.length + 4]
and eax, eax
jnz .next
;; check if first pass
and ebx, ebx
jz .first_pass
mov eax, [edi + mb_mmap.type]
and eax, 0x1 ; check if free
jz .next
;;
mov eax, [bitmap_info]
mov ecx, [mb_mmap.length]
cmp eax, ecx
ja .next
cmp ebx, 0x1
jne .third_pass
mov eax, [edi + mb_mmap.addr]
mov [bitmap_info + bitmap.addr], eax
LOG msg_bitmap_stored_at, eax
call init_bitmap ; mark all memory as used
jmp .bitmap_size_already_set
;; TODO: mark as free in bitmap
.third_pass:
push dword [edi + mb_mmap.length]
push dword [edi + mb_mmap.addr]
call bitmap_mark_range_free
add esp, 8
jmp .next
;; first pass then calculate higher address
.first_pass:
LOG msg_mmap_entry, dword [edi + mb_mmap.addr + 4], \
dword [edi + mb_mmap.addr], \
dword [edi + mb_mmap.length + 4], \
dword [edi + mb_mmap.length], \
dword [edi + mb_mmap.type]
mov eax, [edi + mb_mmap.length]
add eax, [edi + mb_mmap.addr]
jnc .no_overflow
mov eax, -1 ; if overflow set eax to (uint32_t)-1
.no_overflow:
mov edx, [ebp - 4]
cmp edx, eax
ja .next
mov [ebp - 4], eax
.next:
mov eax, [edi + mb_mmap.size]
add eax, 0x4
add edi, eax ; jump to next entry
sub esi, eax
jnz .loop
and ebx, ebx
jnz .bitmap_size_already_set
LOG msg_max_mem, dword [ebp - 4]
mov eax, [ebp - 4]
shr eax, 15 ; eax / (4096*8)
mov [bitmap_info], eax
.bitmap_size_already_set:
mov edi, [ebp + 8] ; mb_mmap struct addr
mov esi, [ebp + 12] ; mmap length
inc ebx
cmp ebx, 2
jbe .loop
pop ebx
pop esi
pop edi
leave
ret
setup_pmm_legacy:
push ebp
mov ebp, esp
push edi
push esi
push ebx
xor eax, eax
mov ecx, [ebp + 8]
shl ecx, 0xA ; ecx * 1KiB
mov esi, ecx
LOG msg_mem_block, eax, ecx
mov eax, 0x100000
mov ecx, [ebp + 12]
shl ecx, 0xA ; ecx * 1KiB
mov ebx, ecx
mov edi, eax
add edi, ecx
LOG msg_mem_block, eax, ecx
LOG msg_max_mem, edi
shr edi, 15 ; (edi / (4046*8))
mov dword [bitmap_info], edi
cmp edi, esi
ja .try_high
mov dword [bitmap_info + bitmap.addr], 0
jmp .initialize_bitmap
.try_high:
mov eax, ebx
sub ebx, kernel_size
cmp edi, ebx
ja .err_no_mem
mov dword [bitmap_info + bitmap.addr], kernel_end
.initialize_bitmap:
call init_bitmap
push esi
push dword 0
call bitmap_mark_range_free
push ebx
push dword 0x100000
call bitmap_mark_range_free
xor eax, eax
jmp .end
.err_no_mem:
mov eax, 1
.end:
pop ebx
pop esi
pop edi
leave
ret
global setup_pmm
setup_pmm:
push ebp
mov ebp, esp
push edi
push esi
push ebx
mov edi, [ebp + 8]
mov eax, [edi]
and eax, 0x40 ; (1 << 6)
jz .no_mmap
push dword [edi + mb_info.mmap_length]
push dword [edi + mb_info.mmap_addr]
call setup_pmm_mmap
add esp, 8
jmp .end_mem_detection
.no_mmap:
LOG warn_no_mmap
mov eax, [edi]
and eax, 0x1
jz .err
push dword [edi + mb_info.mem_upper]
push dword [edi + mb_info.mem_lower]
call setup_pmm_legacy
add esp, 8
.end_mem_detection:
;; mark bitmap as used
xor ebx, ebx
mov edi, [bitmap_info + bitmap.addr]
mov esi, [bitmap_info]
push dword 1 ; bitmap_mark(addr, 1) == set
.loop:
cmp ebx, edi
jnb .end_loop
add edi, ebx
push edi
call bitmap_mark
add esp, 4
add ebx, 0x1000
jmp .loop
.end_loop:
add esp, 4 ; previous "push dword 0"
xor eax, eax
jmp .end
.err:
mov eax, 1
.end:
pop ebx
pop esi
pop ebx
leave
ret
global alloc_frames
alloc_frames:
push esp
mov ebp, esp
push edi
push esi
mov edi, [ebp + 8] ; count
pop esi
pop edi
leave
ret
global free_frames
free_frames:
push esp
mov ebp, esp
call bitmap_mark_range_free
leave
ret
section .data
bitmap_info:
istruc bitmap
at bitmap.length, dd 0
at bitmap.addr, dd 0
iend
section .rodata
warn_no_mmap db "[WARN] mmap flag not set", 0
msg_mmap_entry db "Memory Map Entry:", 0xA
db 0x9, "Address: (hi): %x (lo): %x", 0xA
db 0x9, "Length: (hi): %x (lo): %x", 0xA
db 0x9, "Type: %x", 0
msg_mem_block db "Free Memory:", 0xA
db 0x9, "Address: %x", 0xA
db 0x9, "Length: %x", 0
msg_max_mem db "Max memory: %x", 0
msg_dump_x db "dump: %x", 0
msg_bitmap_stored_at db "Bitmap stored at: %x", 0
file db __FILE__, 0

View file

@ -1,11 +0,0 @@
[BITS 32]
global syscall_table
syscall_table:
dd 0 ; sys_exit
dd 0 ; sys_fork
dd 0 ; sys_read
dd 0 ; sys_write
dd 0 ; sys_open
dd 0 ; sys_close
.end:

View file

@ -1,3 +1,11 @@
SUBDIR = base crypto
SUBDIRS = crypto
include $(TOPDIR)/share/mk/stupid.subdir.mk
TOPGOALS = all clean install
.PHONY: $(SUBDIRS)
$(SUBDIRS):
@echo "📁 lib/$@"
DESTDIR=$(DESTDIR)/lib $(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: $(TOPGOALS)
$(TOPGOALS): $(SUBDIRS)

View file

@ -1,26 +0,0 @@
; file: base.inc
extern log_impl
; macro: LOG
;
; example:
; (start code)
; LOG msg_boot_info, eax
; (end)
%macro LOG 1-*
%ifdef DEBUG
%rep %0
%rotate -1
push %1
%endrep
push file
call log_impl
add esp, 4
%rep %0
add esp, 4
%endrep
%endif
%endmacro

View file

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

View file

@ -1,158 +0,0 @@
; file: log.s
[BITS 32]
%ifdef __KERNEL__
extern serial_write
%endif
section .text
; Function: putstr
;
putstr:
push ebp
mov ebp, esp
push edi
mov edi, [ebp + 8]
.loop:
mov eax, [edi]
cmp al, 0
je .end
push eax
%ifdef __KERNEL__
call serial_write
%else
%endif
add esp, 4
inc edi
jmp .loop
.end:
pop edi
leave
ret
; Function: puthex
;
puthex:
push ebp
mov ebp, esp
push edi
push esi
mov edi, [ebp + 8] ; number
mov eax, hexprefix
push hexprefix
call putstr
add esp, 4
mov edx, 0xF
mov ecx, 0x8
mov esi, buffer
.loop:
rol edi, 4
mov eax, edi
and eax, edx
mov al, [digits + eax]
mov [esi], al
inc esi
dec ecx
jnz .loop
mov eax, buffer
push eax
call putstr
add esp, 4
pop esi
pop edi
leave
ret
; Function: log_impl
;
global log_impl
log_impl:
push ebp
mov ebp, esp
push edi
push esi
push ebx
mov eax, [ebp + 8]
push eax
call putstr
add esp, 4
%ifdef __KERNEL__
mov eax, ':'
push eax
call serial_write
add esp, 4
%else
%endif
mov edi, [ebp + 12]
mov esi, 12
.loop:
mov eax, [edi]
cmp al, 0
je .end
cmp al, '%'
jne .putchar
inc edi
mov eax, [edi]
cmp al, '%'
je .next
cmp al, 'x'
jne .check_s
add esi, 4
mov ebx, ebp
add ebx, esi
mov eax, [ebx]
push eax
call puthex
add esp, 4
jmp .next
.check_s:
cmp al, 's'
jne .unknown_format
add esi, 4
mov ebx, ebp
add ebx, esi
mov eax, [ebx]
push eax
call putstr
add esp, 4
jmp .next
.unknown_format:
mov al, '?'
.putchar:
push eax
%ifdef __KERNEL__
call serial_write
%else
;; TODO
%endif
add esp, 4
.next:
inc edi
jmp .loop
.end:
;; print new line
%ifdef __KERNEL__
mov al, 0xA
push eax
call serial_write
add esp, 4
%else
%endif
pop ebx
pop esi
pop edi
leave
ret
digits db '0123456789ABCDEF'
hexprefix db '0x', 0
buffer db '00000000', 0

View file

@ -1,4 +1,5 @@
LIB = crypto
SRCS = hash/sha256.s
all:
include $(TOPDIR)/share/mk/stupid.lib.mk
clean:
install:

View file

@ -1,5 +0,0 @@
# File: stupid.clean.mk
#
clean:
$(RM) $(CLEANFILES)

View file

@ -1,38 +0,0 @@
# File: stupid.kernel.mk
#
include $(TOPDIR)/share/mk/stupid.own.mk
ifdef KERNEL
ASFLAGS += -D__KERNEL__ -I$(TOPDIR)/kernel
OBJS = $(addsuffix .o, $(basename $(SRCS)))
OBJS-dbg = $(addsuffix .dbg.o, $(basename $(SRCS)))
CLEANFILES += $(KERNEL) $(KERNEL)-dbg $(OBJS) $(OBJS-dbg)
$(KERNEL): $(OBJS)
$(LD) -T $(TOPDIR)/kernel/linker.ld -nostdlib -o $@ $^
$(KERNEL)-dbg: $(OBJS-dbg)
$(LD) -T $(TOPDIR)/kernel/linker.ld -nostdlib -o $@ $^
%.o: %.s
$(AS) $(ASFLAGS) -o $@ $<
%.dbg.o: %.s
$(AS) $(ASFLAGS) $(ASDBGFLAGS) -o $@ $<
lib/%.o: ../lib/base/%.s
@$(MKCWD)
$(AS) $(ASFLAGS) -o $@ $<
lib/%.dbg.o: ../lib/base/%.s
@$(MKCWD)
$(AS) $(ASFLAGS) $(ASDBGFLAGS) -o $@ $<
all: $(KERNEL) $(KERNEL)-dbg
endif
include $(TOPDIR)/share/mk/stupid.clean.mk

View file

@ -1,33 +0,0 @@
# File: stupid.lib.mk
# Support for building libraries
include $(TOPDIR)/share/mk/stupid.own.mk
ifdef LIB
CLEANFILES += lib$(LIB).a
ifdef SRCS
OBJS += $(addsuffix .o, $(basename $(SRCS)))
CLEANFILES += $(OBJS)
lib$(LIB).a: $(OBJS)
$(AR) rcs $@ $^
else
CLEANFILES += $(LIB).o
lib$(LIB).a: $(LIB).o
$(AR) rcs $@ $^
endif
all: lib$(LIB).a
endif
include $(TOPDIR)/share/mk/stupid.clean.mk
include $(TOPDIR)/share/mk/stupid.sys.mk

View file

@ -1,32 +0,0 @@
# File: stupid.own.mk
# Define common variables
ifndef _STUPID_OWN_MK_
_STUPID_OWN_MK_=1
.DEFAULT_GOAL := all
BINDIR = /bin
LIBDIR = /lib
CC = clang -target i386-none-elf
CXX = clang++ -target i386-none-elf
AS = nasm
LD = ld.lld
PLSCC = plsc
OBJCOPY = llvm-objcopy
OBJDUMP = llvm-objdump
MKCWD = mkdir -p $(@D)
TARGETS = all clean install
.PHONY: $(TARGETS)
EXTRAFLAGS = -DSTUPID_VERSION="0.0" -D__STUPID__
CFLAGS += -Wall -Werror -Wextra $(EXTRAFLAGS)
CXXFLAGS += -Wall -Werror -Wextra $(EXTRAFLAGS)
ASFLAGS += -felf -I$(TOPDIR)/lib $(EXTRAFLAGS)
ASDBGFLAGS += -F dwarf -g -DDEBUG
endif

View file

@ -1,41 +0,0 @@
# File: stupid.prog.mk
# Building programs from source files
#
# targets:
# - all:
# build the program and its manual page.
# - clean:
# remove the program and any object files.
# - install:
# install the program and its manual page.
include $(TOPDIR)/share/mk/stupid.own.mk
ifdef PROG
CLEANFILES += $(PROG)
ifdef SRCS
OBJS += $(addsuffix .o, $(basename $(SRCS)))
CLEANFILES += $(OBJS)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^ $(LDADD)
else
CLEANFILES += $(PROG).o
$(PROG): $(PROG).o
$(CC) $(CFLAGS) -o $@ $< $(LDADD)
endif
all: $(PROG)
endif
include $(TOPDIR)/share/mk/stupid.clean.mk
include $(TOPDIR)/share/mk/stupid.sys.mk

View file

@ -1,20 +0,0 @@
# File: stupid.subdir.mk
# Targets for building subdirectories
.DEFAULT_GOAL := all
TOPGOALS = all clean install
ifndef NOSUBDIR
.PHONY: $(SUBDIR)
$(SUBDIR):
$(MAKE) -C $@ $(MAKECMDGOALS)
$(TOPGOALS): $(SUBDIR)
else
# ensure target exist
$(TOPGOALS):
endif

View file

@ -1,19 +0,0 @@
# File: stupid.sys.mk
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
%.o: %.cc
$(CXX) -c -o $@ $< $(CXXFLAGS)
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS)
%.o: %.cxx
$(CXX) -c -o $@ $< $(CXXFLAGS)
%.o: %.C
$(CXX) -c -o $@ $< $(CXXFLAGS)
%.o: %.s
$(AS) $(ASFLAGS) -o $@ $<

3
thirdparty/Makefile vendored
View file

@ -1,3 +0,0 @@
NOSUBDIR := 1
include $(TOPDIR)/share/mk/stupid.subdir.mk

View file

@ -12,20 +12,13 @@ menuentry "StupidOS" {
boot
}
menuentry "StupidOS (debug)" {
hashsum --hash sha256 --check /boot/hashfile --prefix /
multiboot /vmstupid-dbg "lang=en"
boot
}
EOF
)
gen_iso_file() {
mkdir -p "$2/boot/grub"
echo "$grub_config" > "$2/boot/grub/grub.cfg"
sha256sum vmstupid > "$2/boot/hashfile"
sha256sum vmstupid-dbg >> "$2/boot/hashfile"
sha256sum "$2/vmstupid" > "$2/boot/hashfile"
grub-mkrescue -o $1 $2
}