...
This commit is contained in:
3
grub.cfg
3
grub.cfg
@@ -1,3 +1,4 @@
|
||||
menuentry "nub-os" {
|
||||
multiboot2 /boot/kernel.bin
|
||||
multiboot2 /boot/kernel
|
||||
boot
|
||||
}
|
||||
|
||||
14
makefile
14
makefile
@@ -1,7 +1,7 @@
|
||||
CC = i386-elf-gcc
|
||||
LD = i386-elf-ld
|
||||
|
||||
CFLAGS = -ffreestanding -m32
|
||||
CFLAGS = -Werror -Wall -pedantic -std=c23 -ffreestanding -m32
|
||||
|
||||
all: .build/nub-os.iso
|
||||
|
||||
@@ -11,20 +11,20 @@ clean:
|
||||
build-dir:
|
||||
mkdir .build 2>/dev/null || true
|
||||
|
||||
.build/nub-os.iso: build-dir .build/kernel.bin
|
||||
.build/nub-os.iso: build-dir .build/kernel
|
||||
mkdir -p .build/iso/boot/grub
|
||||
cp grub.cfg .build/iso/boot/grub
|
||||
cp .build/kernel.bin .build/iso/boot/
|
||||
cp .build/kernel .build/iso/boot/
|
||||
grub-mkrescue -o .build/nub-os.iso .build/iso/
|
||||
|
||||
.build/kernel.bin: build-dir .build/boot.o .build/kernel.o .build/print.o
|
||||
$(LD) -Ttext 0x100000 -o .build/kernel.bin .build/boot.o .build/kernel.o .build/print.o
|
||||
.build/kernel: build-dir .build/boot.o .build/kernel.o .build/vga.o
|
||||
$(LD) -Ttext 0x100000 -o .build/kernel .build/boot.o .build/kernel.o .build/vga.o
|
||||
|
||||
.build/kernel.o: build-dir src/kernel.c
|
||||
$(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c
|
||||
|
||||
.build/print.o: build-dir src/print.c
|
||||
$(CC) $(CFLAGS) -c -o .build/print.o src/print.c
|
||||
.build/vga.o: build-dir src/vga.c
|
||||
$(CC) $(CFLAGS) -c -o .build/vga.o src/vga.c
|
||||
|
||||
.build/boot.o: build-dir src/boot.asm
|
||||
nasm -f elf32 -o .build/boot.o src/boot.asm
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "print.h"
|
||||
#include "vga.h"
|
||||
|
||||
void kernel_main(void)
|
||||
{
|
||||
print("Welcome to nub OS\n");
|
||||
vga_reset();
|
||||
vga_print("Welcome to nub OS\n");
|
||||
}
|
||||
97
src/print.c
97
src/print.c
@@ -1,97 +0,0 @@
|
||||
#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)
|
||||
|
||||
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, FG_COLOR fg_color, BG_COLOR bg_color)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
cursor_col = 0;
|
||||
cursor_row++;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t color = fg_color | bg_color << 4;
|
||||
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)
|
||||
{
|
||||
print_clr(string, FG_WHITE, BG_BLACK);
|
||||
}
|
||||
|
||||
void print_clr(const char* string, FG_COLOR fg_color, BG_COLOR bg_color)
|
||||
{
|
||||
for (int i = 0; string[i]; i++)
|
||||
{
|
||||
put_char(string[i], fg_color, bg_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;
|
||||
}
|
||||
}
|
||||
40
src/print.h
40
src/print.h
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
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,
|
||||
} FG_COLOR;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
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,
|
||||
} BG_COLOR;
|
||||
|
||||
void put_char(char c, FG_COLOR fg_color, BG_COLOR bg_color);
|
||||
void print(const char* string);
|
||||
void print_clr(const char* string, FG_COLOR fg_color, BG_COLOR bg_color);
|
||||
void clear_screen(void);
|
||||
void set_cursor_position(int row, int col);
|
||||
17
src/stdint.h
Normal file
17
src/stdint.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
typedef signed long int int32_t;
|
||||
typedef unsigned long int uin32_t;
|
||||
|
||||
typedef signed long long int int64_t;
|
||||
typedef unsigned long long int uin64_t;
|
||||
|
||||
#define bool uint8_t;
|
||||
#define true 1
|
||||
#define false 0
|
||||
111
src/vga.c
Normal file
111
src/vga.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "vga.h"
|
||||
|
||||
#define ROWS 25
|
||||
#define COLUMNS 80
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t character;
|
||||
uint8_t color;
|
||||
} vga_char;
|
||||
|
||||
vga_char* vga_buffer = (vga_char*)0xb8000;
|
||||
uint8_t cursor_row = 0;
|
||||
uint8_t cursor_col = 0;
|
||||
|
||||
void vga_set_char(uint8_t row, uint8_t col, vga_char character)
|
||||
{
|
||||
vga_buffer[COLUMNS * row + col] = character;
|
||||
}
|
||||
|
||||
vga_char vga_char_at(uint8_t row, uint8_t col)
|
||||
{
|
||||
return vga_buffer[COLUMNS * row + col];
|
||||
}
|
||||
|
||||
void vga_reset(void)
|
||||
{
|
||||
for (uint8_t row = 0; row < ROWS; row++)
|
||||
{
|
||||
for (uint8_t col = 0; col < COLUMNS; col++)
|
||||
{
|
||||
vga_char character = { .character = ' ', .color = vga_default_color() };
|
||||
vga_set_char(row, col, character);
|
||||
}
|
||||
}
|
||||
|
||||
cursor_row = 0;
|
||||
cursor_col = 0;
|
||||
}
|
||||
|
||||
void vga_set_cursor_position(uint8_t row, uint8_t col)
|
||||
{
|
||||
if (row < ROWS && col < COLUMNS)
|
||||
{
|
||||
cursor_row = row;
|
||||
cursor_col = col;
|
||||
}
|
||||
}
|
||||
|
||||
void vga_print_char(char character, vga_color_t color)
|
||||
{
|
||||
switch (character)
|
||||
{
|
||||
case '\n':
|
||||
{
|
||||
cursor_row += 1;
|
||||
cursor_col = 0;
|
||||
break;
|
||||
}
|
||||
case '\r':
|
||||
{
|
||||
cursor_col = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
vga_char c = { .character = character, .color = color };
|
||||
vga_set_char(cursor_row, cursor_col, c);
|
||||
cursor_col += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor_col >= COLUMNS)
|
||||
{
|
||||
cursor_col = 0;
|
||||
cursor_row += 1;
|
||||
}
|
||||
|
||||
if (cursor_row >= ROWS)
|
||||
{
|
||||
for (uint8_t row = 1; row < ROWS; row++)
|
||||
{
|
||||
for (uint8_t col = 0; col < COLUMNS; col++)
|
||||
{
|
||||
vga_set_char(row, col, vga_char_at(row - 1, col));
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t col = 0; col < COLUMNS; col++)
|
||||
{
|
||||
vga_char character = { .character = ' ', .color = vga_default_color() };
|
||||
vga_set_char(ROWS - 1, col, character);
|
||||
};
|
||||
|
||||
cursor_row = ROWS - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void vga_print_colored(const char* string, vga_color_t color)
|
||||
{
|
||||
for (uint8_t i = 0; string[i] != '\0'; i++)
|
||||
{
|
||||
vga_print_char(string[i], color);
|
||||
}
|
||||
}
|
||||
|
||||
void vga_print(const char* string)
|
||||
{
|
||||
vga_print_colored(string, vga_default_color());
|
||||
}
|
||||
38
src/vga.h
Normal file
38
src/vga.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define VGA_BLACK 0
|
||||
#define VGA_BLUE 1
|
||||
#define VGA_GREEN 2
|
||||
#define VGA_CYAN 3
|
||||
#define VGA_RED 4
|
||||
#define VGA_MAGENTA 5
|
||||
#define VGA_BROWN 6
|
||||
#define VGA_LIGHT_GRAY 7
|
||||
#define VGA_DARK_GRAY 8
|
||||
#define VGA_LIGHT_BLUE 9
|
||||
#define VGA_LIGHT_GREEN 10
|
||||
#define VGA_LIGHT_CYAN 11
|
||||
#define VGA_LIGHT_RED 12
|
||||
#define VGA_LIGHT_MAGENTA 13
|
||||
#define VGA_YELLOW 14
|
||||
#define VGA_WHITE 15
|
||||
|
||||
typedef uint8_t vga_color_t;
|
||||
|
||||
void vga_reset(void);
|
||||
void vga_set_cursor_position(uint8_t row, uint8_t col);
|
||||
|
||||
void vga_print_colored(const char* string, vga_color_t color);
|
||||
void vga_print(const char* string);
|
||||
|
||||
static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color)
|
||||
{
|
||||
return fg_color | bg_color << 4;
|
||||
}
|
||||
|
||||
static inline vga_color_t vga_default_color()
|
||||
{
|
||||
return vga_color(VGA_LIGHT_GRAY, VGA_BLACK);
|
||||
}
|
||||
Reference in New Issue
Block a user