Compare commits
10 Commits
67ef8be1ce
...
c06380137f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c06380137f | ||
|
|
a422756b8c | ||
|
|
597f749470 | ||
|
|
42d8f26abb | ||
|
|
9be2f8a948 | ||
|
|
d11c1072f9 | ||
|
|
3b5e08951c | ||
|
|
e2dcdbeb53 | ||
|
|
6db69608bb | ||
|
|
c3d42e8033 |
@@ -16,3 +16,5 @@ AllowShortLoopsOnASingleLine: false
|
||||
SeparateDefinitionBlocks: Always
|
||||
|
||||
BreakBeforeBraces: Allman
|
||||
|
||||
Cpp11BracedListStyle: false
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1 @@
|
||||
*.bin
|
||||
*.o
|
||||
.build
|
||||
23
README.md
Normal file
23
README.md
Normal 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
|
||||
```
|
||||
BIN
build/kernel.o
BIN
build/kernel.o
Binary file not shown.
Binary file not shown.
4
grub.cfg
Normal file
4
grub.cfg
Normal file
@@ -0,0 +1,4 @@
|
||||
menuentry "nub-os" {
|
||||
multiboot /boot/kernel.bin
|
||||
boot
|
||||
}
|
||||
51
makefile
51
makefile
@@ -1,26 +1,33 @@
|
||||
build: build/os.bin
|
||||
@echo "Build succeded"
|
||||
CC = i386-elf-gcc
|
||||
LD = i386-elf-ld
|
||||
|
||||
run: build/os.bin
|
||||
qemu-system-x86_64 -drive file=build/os.bin,format=raw,index=0,media=disk
|
||||
CFLAGS = -ffreestanding -m32
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
87
src/boot.asm
87
src/boot.asm
@@ -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
21
src/entry.asm
Normal 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:
|
||||
@@ -1,5 +1,6 @@
|
||||
int main(void)
|
||||
#include "print.h"
|
||||
|
||||
void kernel_init(void)
|
||||
{
|
||||
*(char*)0xb8000 = 'A';
|
||||
return 0;
|
||||
print("Starting nub-os\n");
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
section .text
|
||||
[bits 32]
|
||||
[extern main]
|
||||
call main
|
||||
jmp $
|
||||
26
src/mem.c
Normal file
26
src/mem.c
Normal 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
3
src/mem.h
Normal 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
125
src/print.c
Normal 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
8
src/print.h
Normal 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);
|
||||
Reference in New Issue
Block a user