Give up on RYOB, use mb instead

This commit is contained in:
c0repwn3r 2022-05-12 23:08:46 -04:00
parent ac1d0714a0
commit 12193e7920
Signed by: core
GPG Key ID: FDBF740DADDCEECF
22 changed files with 475 additions and 0 deletions

54
Makefile Normal file
View File

@ -0,0 +1,54 @@
ASM ?= nasm
CC := i686-elf-gcc
GDB := i686-elf-gdb
LD := i686-elf-ld
C_FILES = $(shell find src/ -type f -name '*.c')
CO_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES))
ASM_FILES = $(shell find src/kernel/ -type f -name '*.asm')
AO_FILES = $(patsubst src/kernel/%.asm, obj/kernel/%.o, $(ASM_FILES))
KERNEL_O_FILES = ${CO_FILES} ${AO_FILES}
iso: bin/shade.iso
obj/boot.o: src/boot.asm
$(ASM) -felf32 $^ -o $@
bin/shade.bin: obj/boot.o ${KERNEL_O_FILES}
mkdir -p bin
$(CC) -T src/linker.ld -ffreestanding -O2 -nostdlib $^ -o $@ -lgcc
grub-file --is-x86-multiboot bin/shade.bin
bin/shade.iso: bin/shade.bin
mkdir -p isodir/boot/grub
cp bin/shade.bin isodir/boot/shade.bin
cp src/iso/grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o bin/shade.iso isodir
rm -rf isodir
obj/%.o: src/%.c
mkdir -p "$(@D)"
$(CC) -ffreestanding -O2 -Wall -Wextra -c $< -o $@
obj/%.o: src/%.asm
mkdir -p "$(@D)"
$(ASM) -f elf $< -o $@
run: clean bin/shade.iso
qemu-system-x86_64 -hdd bin/shade.iso
debug: clean bin/shade.iso bin/shade.bin
qemu-system-x86_64 -s -S -hdd bin/shade.iso &
${GDB} os-image.bin -ex "symbol-file bin/shade.bin" -ex "target remote localhost:1234"
clean:
find obj -type f -name '*.o' -exec rm {} +
find obj -type f -name '*.bin' -exec rm {} +
find bin -type f -name '*.o' -exec rm {} +
find bin -type f -name '*.bin' -exec rm {} +
find . -type f -name '*.dis' -exec rm {} +
rm -f kernel.elf
rm -rf isodir

BIN
bin/shade.bin Executable file

Binary file not shown.

BIN
bin/shade.iso Normal file

Binary file not shown.

BIN
obj/boot.o Normal file

Binary file not shown.

BIN
obj/kernel/kernel.o Normal file

Binary file not shown.

Binary file not shown.

BIN
obj/kernel/print.o Normal file

Binary file not shown.

BIN
obj/kernel/strings.o Normal file

Binary file not shown.

BIN
obj/kernel/util.o Normal file

Binary file not shown.

38
src/boot.asm Normal file
View File

@ -0,0 +1,38 @@
; Declare constants for the multiboot header.
MBALIGN equ 1 << 0 ; align loaded modules on page boundaries
MEMINFO equ 1 << 1 ; provide memory map
FLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum of above, to prove we are multiboot
section .multiboot
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
section .bss
align 16
stack_bottom:
resb 16384
stack_top:
; _start = entry to kernel
; Since the bootloader will be gone, it doesn't make sense to return from this
section .text
global _start:function (_start.end - _start)
_start:
; 32bit protected mode, no int, no paging
mov esp, stack_top ; Initialize stack
extern kmain
call kmain
cli ; Turn off interrupts in case they are on
.hang:
hlt ; Totally halt the cpu
jmp .hang ; If the cpu un-halts for some reason, halt again
.end:

3
src/iso/grub.cfg Normal file
View File

@ -0,0 +1,3 @@
menuentry "shadeOS Dev Build" {
multiboot /boot/shade.bin
}

55
src/kernel/kernel.c Normal file
View File

@ -0,0 +1,55 @@
#include "./platform/drivers/ports.h"
#include "print.h"
#include "./platform/types.h"
//#include "./platform/interrupts/int.h"
void dummy_test_entrypoint() {}
void kernel_welcome() {
print_str("Welcome to ");
print_set_color(PRINT_COLOR_CYAN, PRINT_COLOR_BLACK);
print_str("Shade");
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
print_str("!\n");
print_str("shadeOS kernel version ");
print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK);
print_str("0.2.2");
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
print_newline();
print_str("Running on ");
print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK);
print_str("shade-development");
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
print_newline();
}
// kMain
void kmain() {
// Initialize screen buffer
struct Char* buffer = (struct Char*) 0xb8000;
clear_all(); // Clear screen
set_cursor_pos(0, 0); // Set cursor position
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set print color
// welcome messages
kernel_msg_ok("Initialized display successfully\n");
kernel_welcome();
print_str("Copyright (c) e3team 2022. All rights reserved.\n");
print_str("This program is provided \"as-is\" and no express or implied warranty is provided.\n");
print_str("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n");
/*
idt_init();
kernel_msg_ok("Interrupts initialized");
__asm__ __volatile__("int $2");
*/
}

View File

@ -0,0 +1,26 @@
/*
* Read 1 byte from specified port
*/
unsigned char port_byte_in(unsigned short port) {
unsigned char result;
// source and dest are backwards.
// "=a (result)" set the C variable to the value of register e'a'x
// '"d" (port) map the C variable port into e'd'x register
__asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
}
void port_byte_out(unsigned short port, unsigned char data) {
// both regs are C vars, nothing is returned, so no '=' in asm syntax
// comma because two vars in input area and none in return area
__asm__("out %%al, %%dx" : : "a" (data), "d" (port));
}
unsigned short port_word_in(unsigned short port) {
unsigned short result;
__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
return result;
}
void port_word_out(unsigned short port, unsigned short data) {
__asm__("out %%ax, %%dx" : : "a" (data), "d" (port));
}

View File

@ -0,0 +1,4 @@
unsigned char port_byte_in(unsigned short port);
void port_byte_out(unsigned short port, unsigned char data);
unsigned short port_word_in(unsigned short port);
void port_word_out(unsigned short port, unsigned short data);

View File

@ -0,0 +1,18 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned int u32;
typedef int i32;
typedef unsigned short u16;
typedef short i16;
typedef unsigned char u8;
typedef char i8;
#define high16(i32) (i32 & 0xffff)
#define low16(i32) ((i32>>16) & 0xffff)
#define TRUE 1
#define FALSE 0
#define NULL 0
#endif

110
src/kernel/print.c Normal file
View File

@ -0,0 +1,110 @@
#include "print.h"
#include "./platform/drivers/ports.h"
int row = 0;
int col = 0;
char color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4;
void clear_row(int row) {
struct Char* buffer = (struct Char*) 0xb8000;
struct Char empty = (struct Char) {
character: ' ',
color: color,
};
for (int x = 0; x < NUM_COLS; x++) {
buffer[x + NUM_COLS * row] = empty;
}
set_cursor_pos(col, row);
}
void clear_all() {
for (int i = 0; i < NUM_ROWS; i++) {
clear_row(i);
}
set_cursor_pos(col, row);
}
void print_newline() {
struct Char* buffer = (struct Char*) 0xb8000;
col = 0;
if (row < NUM_ROWS - 1) {
row++;
return;
}
for (int row = 1; row < NUM_ROWS; row++) {
for (int col = 0; col < NUM_COLS; col++) {
struct Char character = buffer[col + NUM_COLS * row];
buffer[col + NUM_COLS * (row - 1)] = character;
}
}
clear_row(NUM_COLS - 1);
set_cursor_pos(col, row);
}
void print_char(char character) {
struct Char* buffer = (struct Char*) 0xb8000;
if (character == '\n') {
print_newline();
return;
}
if (col > NUM_COLS) {
print_newline();
}
struct Char cr = (struct Char) {
character: character,
color: color,
};
buffer[col + NUM_COLS * row] = cr;
col++;
set_cursor_pos(col, row);
}
void print_str(char* str) {
for (int i = 0; 1; i++) {
char character = (char) str[i];
if (character == '\0') {
return;
}
print_char(character);
}
}
void print_set_color(char foreground, char background) {
color = foreground + (background << 4);
}
void set_cursor_pos(int col, int row) {
int offset = col + NUM_COLS * row;
port_byte_out(REG_SCREEN_CTRL, 14);
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8));
port_byte_out(REG_SCREEN_CTRL, 15);
port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff));
}
void kernel_msg_ok(char* msg) {
char ok_p1[] = "[ ";
char ok_p2[] = "OK ";
char ok_p3[] = "] ";
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
print_str(ok_p1);
print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK);
print_str(ok_p2);
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK);
print_str(ok_p3);
print_str(msg);
}

44
src/kernel/print.h Normal file
View File

@ -0,0 +1,44 @@
#ifndef PRINT_H
#define PRINT_H
#define REG_SCREEN_CTRL 0x3d4
#define REG_SCREEN_DATA 0x3d5
enum {
PRINT_COLOR_BLACK = 0,
PRINT_COLOR_BLUE = 1,
PRINT_COLOR_GREEN = 2,
PRINT_COLOR_CYAN = 3,
PRINT_COLOR_RED = 4,
PRINT_COLOR_MAGENTA = 5,
PRINT_COLOR_BROWN = 6,
PRINT_COLOR_LIGHT_GRAY = 7,
PRINT_COLOR_DARK_GRAY = 8,
PRINT_COLOR_LIGHT_BLUE = 9,
PRINT_COLOR_LIGHT_GREEN = 10,
PRINT_COLOR_LIGHT_CYAN = 11,
PRINT_COLOR_LIGHT_RED = 12,
PRINT_COLOR_PINK = 13,
PRINT_COLOR_YELLOW = 14,
PRINT_COLOR_WHITE = 15,
};
const static int NUM_COLS = 80;
const static int NUM_ROWS = 25;
struct Char {
char character;
char color;
};
void clear_row(int row);
void clear_all();
void print_newline();
void print_char(char character);
void print_set_color(char foreground, char background);
void print_str(char* str);
void set_cursor_pos(int col, int row);
void kernel_msg_ok(char* msg);
#endif

48
src/kernel/strings.c Normal file
View File

@ -0,0 +1,48 @@
#include "strings.h"
#include "./platform/types.h"
void itoa(int n, char str[]) {
int i, sign;
if ((sign = n) < 0) n = -n;
i = 0;
do {
str[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
if (sign < 0) str[i++] = '-';
str[i] = '\0';
strrev(str);
}
/* K&R */
void strrev(char s[]) {
int c, i, j;
for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
/* K&R */
int strlen(char s[]) {
int i = 0;
while (s[i] != '\0') ++i;
return i;
}
char* strcpy(char* strDest, const char* strSrc) {
if ( (strDest == NULL) || (strSrc == NULL) ) {
return NULL;
}
char* strDestCopy = strDest;
while ((*strDest++=*strSrc++)!='\0');
return strDestCopy;
}
char* strcnc(char* str1, char* str2) {
char* str_dest;
strcpy(str_dest, str1);
strcpy(str_dest, str2);
}

10
src/kernel/strings.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef STRINGS_H
#define STRINGS_H
void itoa(int n, char str[]);
void strrev(char s[]);
int strlen(char s[]);
char* strcpy(char* strDest, const char* strSrc);
char* strcnc(char* str1, char* str2);
#endif

25
src/kernel/util.c Normal file
View File

@ -0,0 +1,25 @@
#include "util.h"
void memcpy(char *source, char *dest, int nbytes) {
int i;
for (i = 0; i < nbytes; i++) {
*(dest + i) = *(source + i);
}
}
void memset(char *dest, char val, int len) {
char *temp = (char *)dest;
for(; len !=0; len--) *temp++ = val;
}
void int_to_ascii(int n, char str[]) {
int i, sign;
if ((sign = n) < 0) n = -n;
i = 0;
do {
str[i++] = n % 10 + '0';
} while ((n /= 10) > 0);
if (sign < 0) str[i++] = '-';
str[i] = '\0';
}

8
src/kernel/util.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef UTIL_H
#define UTIL_H
void memcpy(char *source, char *dest, int nbytes);
void memset(char *dest, char val, int len);
void int_to_ascii(int n, char str[]);
#endif

32
src/linker.ld Normal file
View File

@ -0,0 +1,32 @@
ENTRY(_start)
SECTIONS
{
. = 1M;
/* MB header */
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
}