Compare commits

...

10 Commits

Author SHA1 Message Date
nub31
c06380137f remove redundant readme command 2025-08-23 17:24:53 +02:00
nub31
a422756b8c docs 2025-08-23 17:23:03 +02:00
nub31
597f749470 ... 2025-08-23 17:07:42 +02:00
nub31
42d8f26abb move to grub 2025-08-23 16:54:09 +02:00
nub31
9be2f8a948 ... 2025-08-23 16:24:45 +02:00
nub31
d11c1072f9 ... 2025-08-23 15:52:54 +02:00
nub31
3b5e08951c move stuff aroundd 2025-08-23 14:43:00 +02:00
nub31
e2dcdbeb53 simplified print 2025-08-22 23:59:03 +02:00
nub31
6db69608bb kernel print and mem 2025-08-22 23:39:38 +02:00
nub31
c3d42e8033 ... 2025-08-22 22:36:29 +02:00
15 changed files with 247 additions and 120 deletions

View File

@@ -16,3 +16,5 @@ AllowShortLoopsOnASingleLine: false
SeparateDefinitionBlocks: Always
BreakBeforeBraces: Allman
Cpp11BracedListStyle: false

3
.gitignore vendored
View File

@@ -1,2 +1 @@
*.bin
*.o
.build

23
README.md Normal file
View File

@@ -0,0 +1,23 @@
# Nub OS
## Dependencies
- `make`
- `grub`
- `mtools`
- `i386-elf-gcc`
- `i386-elf-ld`
## Building
```sh
make
```
## Running
After building, run the following:
```sh
qemu-system-x86_64 -cdrom .build/nub-os.iso
```

Binary file not shown.

Binary file not shown.

4
grub.cfg Normal file
View File

@@ -0,0 +1,4 @@
menuentry "nub-os" {
multiboot /boot/kernel.bin
boot
}

View File

@@ -1,26 +1,33 @@
build: build/os.bin
@echo "Build succeded"
run: build/os.bin
qemu-system-x86_64 -drive file=build/os.bin,format=raw,index=0,media=disk
CC = i386-elf-gcc
LD = i386-elf-ld
build/os.bin: build/boot.bin build/kernel.bin build/zeroes.bin
cat build/boot.bin build/kernel.bin build/zeroes.bin > build/os.bin
CFLAGS = -ffreestanding -m32
build/kernel.bin: build/kernel.o build/kernel_entry.o
i386-elf-ld -o build/kernel.bin -Ttext 0x1000 build/kernel_entry.o build/kernel.o --oformat binary
build/kernel.o: src/kernel.c
i386-elf-gcc -ffreestanding -m32 -c -o build/kernel.o src/kernel.c
build/kernel_entry.o: src/kernel_entry.asm
nasm -f elf -o build/kernel_entry.o src/kernel_entry.asm
build/boot.bin: src/boot.asm
nasm -f bin -o build/boot.bin src/boot.asm
build/zeroes.bin:
dd if=/dev/zero of=build/zeroes.bin bs=1 count=10240
all: .build/nub-os.iso
clean:
@rm build/* 2>/dev/null || true
@rm -r .build 2>/dev/null || true
build-dir:
mkdir .build 2>/dev/null || true
.build/nub-os.iso: build-dir .build/kernel.bin
mkdir -p .build/iso/boot/grub
cp grub.cfg .build/iso/boot/grub
cp .build/kernel.bin .build/iso/boot/
grub-mkrescue -o .build/nub-os.iso .build/iso/
.build/kernel.bin: build-dir .build/entry.o .build/kernel.o .build/mem.o .build/print.o
$(LD) -Ttext 0x100000 -o .build/kernel.bin .build/entry.o .build/kernel.o .build/mem.o .build/print.o
.build/kernel.o: build-dir src/kernel.c
$(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c
.build/mem.o: build-dir src/mem.c
$(CC) $(CFLAGS) -c -o .build/mem.o src/mem.c
.build/print.o: build-dir src/print.c
$(CC) $(CFLAGS) -c -o .build/print.o src/print.c
.build/entry.o: build-dir src/entry.asm
nasm -f elf -o .build/entry.o src/entry.asm

View File

@@ -1,87 +0,0 @@
[org 0x7c00]
[bits 16]
KERNEL_LOCATION equ 0x1000
mov [BOOT_DISK], dl
xor ax, ax
mov es, ax
mov ds, ax
mov bp, 0x8000
mov sp, bp
mov bx, KERNEL_LOCATION
mov dh, 2
mov ah, 0x02
mov al, dh
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
mov dl, [BOOT_DISK]
int 0x13
mov ah, 0x0
mov al, 0x3
int 0x10
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG:start_protected_mode
jmp $
BOOT_DISK: db 0
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_code:
dw 0xffff
dw 0x0
db 0x0
db 0b10011010
db 0b11001111
db 0x0
gdt_data:
dw 0xffff
dw 0x0
db 0x0
db 0b10010010
db 0b11001111
db 0x0
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
[bits 32]
start_protected_mode:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000
mov esp, ebp
jmp KERNEL_LOCATION
jmp $
times 510-($-$$) db 0
dw 0xaa55

21
src/entry.asm Normal file
View File

@@ -0,0 +1,21 @@
extern kernel_init
section .multiboot
align 4
dd 0x1BADB002 ; multiboot magic number
dd 0x0 ; flags
dd -(0x1BADB002+0x0) ; checksum
section .text
global _start
_start:
cli
mov esp, stack_top
call kernel_init
.hang:
hlt
jmp .hang
section .bss
resb 8192
stack_top:

View File

@@ -1,5 +1,6 @@
int main(void)
#include "print.h"
void kernel_init(void)
{
*(char*)0xb8000 = 'A';
return 0;
}
print("Starting nub-os\n");
}

View File

@@ -1,5 +0,0 @@
section .text
[bits 32]
[extern main]
call main
jmp $

26
src/mem.c Normal file
View File

@@ -0,0 +1,26 @@
#include "mem.h"
void* memcpy(void* dest, const void* src, long n)
{
char* d = dest;
const char* s = src;
for (long i = 0; i < n; i++)
d[i] = s[i];
return dest;
}
void* memset(void* dest, int val, long n)
{
char* d = dest;
for (long i = 0; i < n; i++)
d[i] = val;
return dest;
}
long strlen(const char* str)
{
long len = 0;
while (str[len])
len++;
return len;
}

3
src/mem.h Normal file
View File

@@ -0,0 +1,3 @@
void* memcpy(void* dest, const void* src, long n);
void* memset(void* dest, int val, long n);
long strlen(const char* str);

125
src/print.c Normal file
View File

@@ -0,0 +1,125 @@
#include "print.h"
#include <stdint.h>
#define ROWS 25
#define COLUMNS 80
#define BUF_SIZE ((ROWS * COLUMNS) * 2)
#define BUF_START 0xb8000
#define BUF_END (BUF_START + BUF_SIZE)
enum FG_COLOR
{
FG_BLACK = 0x0,
FG_BLUE = 0x1,
FG_GREEN = 0x2,
FG_CYAN = 0x3,
FG_RED = 0x4,
FG_MAGENTA = 0x5,
FG_BROWN = 0x6,
FG_LIGHT_GRAY = 0x7,
FG_DARK_GRAY = 0x8,
FG_LIGHT_BLUE = 0x9,
FG_LIGHT_GREEN = 0xA,
FG_LIGHT_CYAN = 0xB,
FG_LIGHT_RED = 0xC,
FG_LIGHT_MAGENTA = 0xD,
FG_YELLOW = 0xE,
FG_WHITE = 0xF,
};
enum BG_COLOR
{
BG_BLACK = 0x0,
BG_BLUE = 0x1,
BG_GREEN = 0x2,
BG_CYAN = 0x3,
BG_RED = 0x4,
BG_MAGENTA = 0x5,
BG_BROWN = 0x6,
BG_LIGHT_GRAY = 0x7,
};
typedef struct
{
uint8_t character;
uint8_t color;
} vga_char;
static vga_char* vga_buffer = (vga_char*)BUF_START;
static int cursor_row = 0;
static int cursor_col = 0;
void scroll(void)
{
for (int row = 1; row < ROWS; row++)
{
for (int col = 0; col < COLUMNS; col++)
{
vga_buffer[(row - 1) * COLUMNS + col] = vga_buffer[row * COLUMNS + col];
}
}
for (int col = 0; col < COLUMNS; col++)
{
vga_buffer[(ROWS - 1) * COLUMNS + col] = (vga_char){ ' ', FG_WHITE | BG_BLACK << 4 };
}
}
void put_char(char c, uint8_t color)
{
if (c == '\n')
{
cursor_col = 0;
cursor_row++;
}
else
{
vga_buffer[cursor_row * COLUMNS + cursor_col] = (vga_char){ c, color };
cursor_col++;
}
if (cursor_col >= COLUMNS)
{
cursor_col = 0;
cursor_row++;
}
if (cursor_row >= ROWS)
{
scroll();
cursor_row = ROWS - 1;
}
}
void print(const char* string)
{
uint8_t color = FG_WHITE | BG_BLACK << 4;
for (int i = 0; string[i]; i++)
{
put_char(string[i], color);
}
}
void clear_screen(void)
{
uint8_t color = FG_WHITE | BG_BLACK << 4;
for (int i = 0; i < ROWS * COLUMNS; i++)
{
vga_buffer[i] = (vga_char){ ' ', color };
}
cursor_row = 0;
cursor_col = 0;
}
void set_cursor_position(int row, int col)
{
if (row >= 0 && row < ROWS && col >= 0 && col < COLUMNS)
{
cursor_row = row;
cursor_col = col;
}
}

8
src/print.h Normal file
View File

@@ -0,0 +1,8 @@
#include <stdint.h>
void kernel_print(const char* string);
void put_char(char c, uint8_t color);
void print(const char* string);
void clear_screen(void);
void set_cursor_position(int row, int col);