Skip to content

Commit

Permalink
Repo setup
Browse files Browse the repository at this point in the history
  • Loading branch information
arda-guler committed Sep 4, 2023
1 parent f94d9b7 commit 8043f08
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 0 deletions.
Binary file added bin/kikaos.iso
Binary file not shown.
Binary file added images/kikaos.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions scripts/build_iso.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

i686-elf-as boot.s -o boot.o
i686-elf-gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
i686-elf-gcc -T linker.ld -o kikaos.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
cp kikaos.bin isodir/boot/kikaos.bin
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o kikaos.iso isodir

5 changes: 5 additions & 0 deletions scripts/quick.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

./build_iso.sh
./test_os.sh

4 changes: 4 additions & 0 deletions scripts/test_os.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

qemu-system-i386 -cdrom kikaos.iso

31 changes: 31 additions & 0 deletions src/boot.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.set ALIGN, 1<<0 /* align loaded modules on page boundaries */
.set MEMINFO, 1<<1 /* provide memory map */
.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */

.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM

.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:

.section .text
.global _start
.type _start, @function
_start:

mov $stack_top, %esp
call main

cli
1: hlt
jmp 1b

.size _start, . - _start
3 changes: 3 additions & 0 deletions src/grub.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
menuentry "KikaOS" {
multiboot /boot/kikaos.bin
}
231 changes: 231 additions & 0 deletions src/kernel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#if defined(__linux__)
#error "Use a GCC Cross-Compiler. Terminating..."
#endif

#if !defined(__i386__)
#error "Use an ix86-elf compiler. Terminating..."
#endif

enum vga_color {
VGA_COLOR_BLACK = 0,
VGA_COLOR_BLUE = 1,
VGA_COLOR_GREEN = 2,
VGA_COLOR_CYAN = 3,
VGA_COLOR_RED = 4,
VGA_COLOR_MAGENTA = 5,
VGA_COLOR_BROWN = 6,
VGA_COLOR_LIGHT_GREY = 7,
VGA_COLOR_DARK_GREY = 8,
VGA_COLOR_LIGHT_BLUE = 9,
VGA_COLOR_LIGHT_GREEN = 10,
VGA_COLOR_LIGHT_CYAN = 11,
VGA_COLOR_LIGHT_RED = 12,
VGA_COLOR_LIGHT_MAGENTA = 13,
VGA_COLOR_LIGHT_BROWN = 14,
VGA_COLOR_WHITE = 15,
};

char ASCII[128] =
{
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', /* <-- Tab */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
0, /* <-- control key */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
'*',
0, /* Alt */
' ', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};

static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
{
return fg | bg << 4;
}

static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
{
return (uint16_t) uc | (uint16_t) color << 8;
}

size_t strlen(const char* str)
{
size_t len = 0;
while (str[len])
len++;
return len;
}

static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;

size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;

void terminal_init(void)
{
terminal_row = 0;
terminal_column = 0;
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
terminal_buffer = (uint16_t*) 0xB8000;
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(' ', terminal_color);
}
}
}

void terminal_setColor(uint8_t color)
{
terminal_color = color;
}

void terminal_putEntryAt(char c, uint8_t color, size_t x, size_t y)
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(c, color);
}

void terminal_putChar(char c)
{
// this is the new line character
if (c == '\n') {
if (terminal_row + 1 >= VGA_HEIGHT) {
terminal_scroll();
}
else{
terminal_row = terminal_row + 1;
}
terminal_column = 0;
}

// this is a regular character, print it normally
else {
terminal_putEntryAt(c, terminal_color, terminal_column, terminal_row);

if (terminal_column + 1 >= VGA_WIDTH) {
terminal_column = 0;

if (terminal_row + 1 >= VGA_HEIGHT) {
terminal_scroll();
}
else {
terminal_row = terminal_row + 1;
}

}
else {
terminal_column = terminal_column + 1;
}
}
}

void terminal_scroll(void)
{
// loop through all lines
for (size_t idx_y = 1; idx_y < VGA_HEIGHT; idx_y++){
for (size_t idx_x = 0; idx_x < VGA_WIDTH; idx_x++) {

size_t idx_terminal_read = idx_y * VGA_WIDTH + idx_x;

// get the character at the index we are currently reading
uint16_t current_vga_char = terminal_buffer[idx_terminal_read];

// print it on the line above
size_t idx_terminal_write = (idx_y - 1) * VGA_WIDTH + idx_x;
terminal_buffer[idx_terminal_write] = current_vga_char;
terminal_buffer[idx_terminal_read] = vga_entry(' ', terminal_color);
}
}
}

void terminal_print(const char* data, size_t size)
{
for (size_t i = 0; i < size; i++) {
terminal_putChar(data[i]);
}
}

void terminal_printString(const char* data)
{
terminal_print(data, strlen(data));
}

void outb( unsigned short port, unsigned char val )
{
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port) );
}

static __inline unsigned char inb (unsigned short int port)
{
unsigned char v;

asm volatile("inb %w1,%0":"=a" (v):"Nd" (port));
return v;
}

char get_kbd(char c)
{
if (inb(0x60) != c){
c = inb(0x60);
}

return c;
}

// this is probably one of the worst implementations of 'wait' ever.
// P.S. I don't have interrupts.
void wait(size_t wait_time){
for (size_t ticks=0; ticks < wait_time * 1000000000; ticks++) {
asm volatile("nop");
}
}

void main(void)
{
terminal_init();
terminal_printString("= = = KikaOS = = =\n\n");
terminal_printString("Write or draw away!\n > ");

// writes keyboard input onto the screen
char c_inp = 0;
while(c_inp != 1) {

c_inp = get_kbd(c_inp);

if (c_inp > 0) {
terminal_putChar(ASCII[c_inp]);
wait(1);
}
}
}

37 changes: 37 additions & 0 deletions src/linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
ENTRY(_start)

SECTIONS
{
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
loaded at by the bootloader. */
. = 1M;

/* First put the multiboot header, as it is required to be put very early
early in the image or the bootloader won't recognize the file format.
Next we'll put the .text section. */
.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)
}

}

0 comments on commit 8043f08

Please sign in to comment.