Merge into main the new state of the operating system/kernel #1
							
								
								
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@ -1,2 +1,4 @@
 | 
			
		||||
*.pdf filter=lfs diff=lfs merge=lfs -text
 | 
			
		||||
*.png filter=lfs diff=lfs merge=lfs -text
 | 
			
		||||
*.svg filter=lfs diff=lfs merge=lfs -text
 | 
			
		||||
demodisk.img filter=lfs diff=lfs merge=lfs -text
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1 +1,8 @@
 | 
			
		||||
build
 | 
			
		||||
build
 | 
			
		||||
CON
 | 
			
		||||
.vscode
 | 
			
		||||
isodir/
 | 
			
		||||
root/
 | 
			
		||||
*.iso
 | 
			
		||||
*.img
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								Makefile
									
									
									
									
									
								
							@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
 | 
			
		||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++ 
 | 
			
		||||
CFLAGS =  -ffreestanding -O2 -Wall -Wextra
 | 
			
		||||
 | 
			
		||||
OFILES =	$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o
 | 
			
		||||
OFILES =	$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o
 | 
			
		||||
 | 
			
		||||
SRC_DIR = src
 | 
			
		||||
BUILD_DIR = build
 | 
			
		||||
@ -19,12 +19,27 @@ OBJ_LINK_LIST = $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OFILES) $(CRTEND_OBJ) $(CRTN_OBJ)
 | 
			
		||||
INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
all: clean build
 | 
			
		||||
all: clean build clean_up
 | 
			
		||||
 | 
			
		||||
build: build_kernel run 
 | 
			
		||||
build: build_kernel 
 | 
			
		||||
 | 
			
		||||
run:
 | 
			
		||||
	$(EMULATOR) -d int -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
clean_iso: 
 | 
			
		||||
	if [[ -a isodir/* ]] ; then rm isodir/* -d ; fi
 | 
			
		||||
	if [ -f barinkOS.iso ] ; then rm barinkOS.iso ; fi
 | 
			
		||||
	
 | 
			
		||||
iso: clean_iso build
 | 
			
		||||
	mkdir -p isodir/boot/grub
 | 
			
		||||
	cp build/myos.bin isodir/boot/myos.bin
 | 
			
		||||
	cp src/grub.cfg isodir/boot/grub/grub.cfg
 | 
			
		||||
	grub-mkrescue -o barinkOS.iso isodir
 | 
			
		||||
	
 | 
			
		||||
clean_up:
 | 
			
		||||
	rm build/*.o
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	$(EMULATOR)  -kernel $(BUILD_DIR)/myos.bin -serial file:CON -vga std -monitor stdio -display gtk -m 2G -cpu core2duo 
 | 
			
		||||
 | 
			
		||||
build_kernel: $(OBJ_LINK_LIST)
 | 
			
		||||
	
 | 
			
		||||
@ -56,11 +71,14 @@ $(BUILD_DIR)/crtn.o:
 | 
			
		||||
$(BUILD_DIR)/io.o:
 | 
			
		||||
		$(CPP) -c $(SRC_DIR)/kernel/io.cpp  -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/MMU.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti 
 | 
			
		||||
$(BUILD_DIR)/PageDirectory.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti 
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/idt.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/arch/i386/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/pic.o:
 | 
			
		||||
	$(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti
 | 
			
		||||
 | 
			
		||||
$(BUILD_DIR)/string.o:
 | 
			
		||||
	$(CC) -c $(SRC_DIR)/libc/include/string.c  -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
								
							@ -1,24 +1,26 @@
 | 
			
		||||
# Writing an Operating system 
 | 
			
		||||
## As a learning experience!
 | 
			
		||||
 Inspired by people like Linus Torvalds and Andreas Kling
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
________________________
 | 
			
		||||
### Screenshot(s)
 | 
			
		||||
<img src="screenshots/Screenshot1.png"></img>
 | 
			
		||||
   \
 | 
			
		||||
The first scrolling boot screen. 😲
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<img src="screenshots/WIP_interruptHandling.png"></img>
 | 
			
		||||
   \
 | 
			
		||||
W.I.P - Working on interrupt handling
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 \
 | 
			
		||||
Multiboot information can be read by the kernel.
 | 
			
		||||
________________________
 | 
			
		||||
 | 
			
		||||
### The goal
 | 
			
		||||
Writing a hobby operating system to better understand the basic building blocks of any operating system.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
________________________
 | 
			
		||||
### Operating System Technical specs/details
 | 
			
		||||
The operating system can print strings to the 
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								TODO.md
									
									
									
									
									
								
							@ -3,14 +3,14 @@
 | 
			
		||||
<input type="checkbox" checked/> Setup Cross-Compiler \
 | 
			
		||||
<input type="checkbox" checked/> Multiboot to kernel \
 | 
			
		||||
<input type="checkbox" checked/> Printing string to the screen \
 | 
			
		||||
<input type="checkbox" /> Printing values/numbers to the screen (a.k.k itoa) \
 | 
			
		||||
<input type="checkbox" /> Extend Multiboot implementation \
 | 
			
		||||
<input type="checkbox" checked/> Printing values/numbers to the screen (a.k.k itoa) \
 | 
			
		||||
<input type="checkbox" checked/> Extend Multiboot implementation \
 | 
			
		||||
<input type="checkbox" checked/> Output to serial port \
 | 
			
		||||
<input type="checkbox" /> Move to protected mode \
 | 
			
		||||
<input type="checkbox" /> Enabel CMOS clock \
 | 
			
		||||
<input type="checkbox" checked/> Move to protected mode \
 | 
			
		||||
<input type="checkbox" checked/> Enabel CMOS clock \
 | 
			
		||||
<input type="checkbox" /> Time measurement (PIC &| PIT) \
 | 
			
		||||
<input type="checkbox" /> Detect CPU speed \
 | 
			
		||||
<input type="checkbox" /> Interrupt / exception system (API) \
 | 
			
		||||
<input type="checkbox" checked/> Interrupt / exception system (API) \
 | 
			
		||||
 | 
			
		||||
<input type="checkbox" /> Plan your memory map (virtual, and physical) : decide where you want the data to be. \
 | 
			
		||||
<input type="checkbox" /> The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \
 | 
			
		||||
@ -37,4 +37,4 @@
 | 
			
		||||
<input type="checkbox" /> Basic Window server/client \
 | 
			
		||||
## Support for more filesystems if I like the challenge in writing these ...
 | 
			
		||||
<input type="checkbox" /> FAT Filesystem \
 | 
			
		||||
<input type="checkbox" /> EXT2 Filesystem \
 | 
			
		||||
<input type="checkbox" /> EXT2 Filesystem \
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								images/BarinkOS.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/BarinkOS.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								images/BarinkOS_logo(standard).svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/BarinkOS_logo(standard).svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								images/BarinkOS_logo.svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/BarinkOS_logo.svg
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								screenshots/multiboot.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/multiboot.png
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3
									
								
								src/grub.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/grub.cfg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
menuentry "BarinkOS"{
 | 
			
		||||
    multiboot /boot/myos.bin
 | 
			
		||||
}
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
extern "C" void loadPageDirectory (long unsigned int* addr );
 | 
			
		||||
extern "C" void enablePaging();
 | 
			
		||||
 | 
			
		||||
class MMU {
 | 
			
		||||
    public:
 | 
			
		||||
    void enable ();
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
    uint32_t page_directory[1024] __attribute__((aligned(4096)));
 | 
			
		||||
    uint32_t first_page_table[1024] __attribute__((aligned(4096)));
 | 
			
		||||
};
 | 
			
		||||
@ -21,7 +21,6 @@ stack_bottom:
 | 
			
		||||
stack_top:
 | 
			
		||||
 
 | 
			
		||||
.section .text
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
* Interupt handlers
 | 
			
		||||
*/
 | 
			
		||||
@ -382,6 +381,7 @@ irq15:
 | 
			
		||||
	push $15
 | 
			
		||||
	jmp irq_common
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
irq_common:
 | 
			
		||||
	pusha
 | 
			
		||||
 | 
			
		||||
@ -469,10 +469,22 @@ loadPageDirectory:
 | 
			
		||||
.type _start, @function
 | 
			
		||||
_start:
 | 
			
		||||
	/*Setup the stack pointer to point to the beginning of our stack */
 | 
			
		||||
	/* I believe its a hight address growing down to lower adress for the stack on x86*/
 | 
			
		||||
	/* I believe its a high address growing down to lower adress for the stack on x86*/
 | 
			
		||||
	mov $stack_top, %esp
 | 
			
		||||
 | 
			
		||||
	/*Reset EFLAGS*/
 | 
			
		||||
	pushl $0 
 | 
			
		||||
	popf 
 | 
			
		||||
 | 
			
		||||
	/* push the pointer to the Multiboot information structure*/
 | 
			
		||||
	pushl %ebx
 | 
			
		||||
 | 
			
		||||
	/* push the magic value */
 | 
			
		||||
	pushl %eax
 | 
			
		||||
	
 | 
			
		||||
	call early_main
 | 
			
		||||
	cli
 | 
			
		||||
	
 | 
			
		||||
	load_gdt:
 | 
			
		||||
		lgdt gdt
 | 
			
		||||
 | 
			
		||||
@ -552,4 +564,4 @@ gdt_kdata:
 | 
			
		||||
.byte 0b10010010         # 1st flags | type flags
 | 
			
		||||
.byte 0b11001111         # 2nd flags | limit
 | 
			
		||||
.byte 0x0                # base
 | 
			
		||||
gdt_end:
 | 
			
		||||
gdt_end:
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#include "gdtc.h"
 | 
			
		||||
 | 
			
		||||
#include "../tty/kterm.h"
 | 
			
		||||
 
 | 
			
		||||
gdtEntry_t gdt[3];
 | 
			
		||||
 | 
			
		||||
@ -18,8 +18,10 @@ void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setupGdt(){
 | 
			
		||||
 | 
			
		||||
   printf("setupGdt is called!");
 | 
			
		||||
   gdtPointer.limit   = (sizeof(gdtEntry_t) * 3) - 1;
 | 
			
		||||
   gdtPointer.base      = &gdt;
 | 
			
		||||
   gdtPointer.base    = &gdt;
 | 
			
		||||
 | 
			
		||||
   gdtSetGate(0, 0, 0, 0, 0);
 | 
			
		||||
   gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
extern "c"{
 | 
			
		||||
extern "C"{
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
   uint16_t           lLimit;
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ void irq_handler (registers regs) {
 | 
			
		||||
            // Keyboard interrupt !!
 | 
			
		||||
 | 
			
		||||
            int scan;
 | 
			
		||||
            register int i;
 | 
			
		||||
            /*register*/int i;
 | 
			
		||||
 | 
			
		||||
            // Read scancode 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,6 @@
 | 
			
		||||
extern "C"{
 | 
			
		||||
    #include "../tty/kterm.h"
 | 
			
		||||
}
 | 
			
		||||
#define AS_KERNEL() (  kterm_writestring("[KERNEL]:"))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
 | 
			
		||||
@ -6,10 +6,11 @@ ENTRY(_start)
 | 
			
		||||
   kernel image. */
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
	/* Begin putting sections at 1 MiB, a conventional place for kernels to be
 | 
			
		||||
	   loaded at by the bootloader. */
 | 
			
		||||
	. = 1M;
 | 
			
		||||
 
 | 
			
		||||
 	kernel_begin = .;
 | 
			
		||||
	/* 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. */
 | 
			
		||||
@ -40,4 +41,7 @@ SECTIONS
 | 
			
		||||
 
 | 
			
		||||
	/* The compiler may produce other sections, by default it will put them in
 | 
			
		||||
	   a segment with the same name. Simply add stuff here as needed. */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	kernel_end = .;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ void PIC_sendEOI (unsigned char irq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint16_t __pic_get_irq_reg(int ocw3);
 | 
			
		||||
//static uint16_t __pic_get_irq_reg(int ocw3);
 | 
			
		||||
uint16_t pic_get_irr(void);
 | 
			
		||||
uint16_t pic_get_isr(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
#include "kterm.h"
 | 
			
		||||
 | 
			
		||||
static const size_t VGA_WIDTH = 80;
 | 
			
		||||
static const size_t VGA_HEIGHT = 25;
 | 
			
		||||
 | 
			
		||||
@ -46,6 +47,48 @@ void kterm_putat (char c, uint8_t color, size_t x, size_t y ) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void enable_cursor (uint8_t start_cursor , uint8_t end_cursor ){
 | 
			
		||||
    outb(0x3D4, 0x0A);
 | 
			
		||||
    outb(0x3D5, (inb(0x3D5) & 0xC0) | start_cursor);
 | 
			
		||||
 | 
			
		||||
    outb(0x3D4, 0x0B);
 | 
			
		||||
    outb(0x3D5, (inb(0x3D5) & 0xE0) | end_cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void disable_cursor() 
 | 
			
		||||
{
 | 
			
		||||
        outb(0x3D4, 0x0A);
 | 
			
		||||
        outb(0x3D5, 0x20);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void update_cursor(int x, int y){
 | 
			
		||||
    uint16_t pos = y * VGA_WIDTH + x;
 | 
			
		||||
 | 
			
		||||
    outb(0x3D4, 0x0F);
 | 
			
		||||
    outb(0x3D5, (uint8_t) (pos & 0xFF));
 | 
			
		||||
    outb(0x3D4, 0x0E);
 | 
			
		||||
    outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t get_cursor_position(){
 | 
			
		||||
    uint16_t pos = 0;
 | 
			
		||||
    outb(0x3D4, 0x0F);
 | 
			
		||||
    pos |= inb(0x3D5);
 | 
			
		||||
    outb(0x3D4, 0x0E);
 | 
			
		||||
    pos |= ((uint16_t) inb(0x3D5)) << 8;
 | 
			
		||||
    return pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int get_cursor_x (uint16_t cursor_pos) {
 | 
			
		||||
    return cursor_pos % VGA_WIDTH;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int get_cursor_y (uint16_t cursor_pos ) {
 | 
			
		||||
    return cursor_pos / VGA_WIDTH;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *  With the help from:
 | 
			
		||||
@ -63,6 +106,7 @@ void kterm_scrollup(){
 | 
			
		||||
 | 
			
		||||
void kterm_put (char c) {
 | 
			
		||||
    if(++kterm_column == VGA_WIDTH || c == '\n' ) {
 | 
			
		||||
        update_cursor(kterm_column , kterm_row);
 | 
			
		||||
        kterm_column = 0;
 | 
			
		||||
        if(kterm_row == VGA_HEIGHT-1 ) {       
 | 
			
		||||
            kterm_scrollup();
 | 
			
		||||
@ -88,7 +132,7 @@ void kterm_write(const char* data, size_t size) {
 | 
			
		||||
}   
 | 
			
		||||
 | 
			
		||||
void kterm_writestring(const char* data ){
 | 
			
		||||
    AS_KERNEL();
 | 
			
		||||
   // AS_KERNEL();
 | 
			
		||||
    kterm_write(data, strlen(data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -158,8 +202,10 @@ void printf ( const char *format, ...) {
 | 
			
		||||
            switch (c)
 | 
			
		||||
            {
 | 
			
		||||
            case 'd':
 | 
			
		||||
 | 
			
		||||
                kterm_writestring("Not implemented!!");
 | 
			
		||||
                break;
 | 
			
		||||
            case 'u':
 | 
			
		||||
                break;
 | 
			
		||||
            case 'x':
 | 
			
		||||
                itoa(buf, c, *((int *) arg++));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,12 +5,18 @@
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#include "../vga/colors.h"
 | 
			
		||||
#include "../../../io.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "./../../../../libc/include/string.h"
 | 
			
		||||
 | 
			
		||||
void kterm_init();
 | 
			
		||||
 | 
			
		||||
/* Kernel terminal - Colour functions*/
 | 
			
		||||
void kterm_resetcolor();
 | 
			
		||||
void kterm_setcolor(uint8_t);
 | 
			
		||||
 | 
			
		||||
/* Kernel terminal - Printing function */
 | 
			
		||||
void kterm_putat(char, uint8_t, size_t, size_t);
 | 
			
		||||
void kterm_put(char);
 | 
			
		||||
void kterm_write(const char*, size_t);
 | 
			
		||||
@ -18,9 +24,18 @@ void kterm_writestring(const char*);
 | 
			
		||||
void kterm_scrollup();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Kernel terminal - Cursor functions */
 | 
			
		||||
void enable_cursor (uint8_t start_cursor , uint8_t end_cursor );
 | 
			
		||||
void disable_cursor();
 | 
			
		||||
void update_cursor(int x, int y);
 | 
			
		||||
uint16_t get_cursor_position();
 | 
			
		||||
int get_cursor_x (uint16_t cursor_pos);
 | 
			
		||||
int get_cursor_y (uint16_t cursor_pos);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void printf ( const char *format, ...);
 | 
			
		||||
 | 
			
		||||
static void itoa (char *buf, int base, int d);
 | 
			
		||||
//static void itoa (char *buf, int base, int d);
 | 
			
		||||
 | 
			
		||||
#define KernelTag "[Kernel]: "
 | 
			
		||||
#define AS_KERNEL() (  kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								src/kernel/arch/i386/vga/VBE.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/kernel/arch/i386/vga/VBE.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
 | 
			
		||||
#define VBE_DISPI_IOPORT_INDEX 0x01CE
 | 
			
		||||
#define VBE_DISPI_IOPORT_DATA 0x01CF
 | 
			
		||||
 | 
			
		||||
/* VBE index values*/
 | 
			
		||||
#define VBE_DISPI_INDEX_ID              0x0
 | 
			
		||||
#define VBE_DISPI_INDEX_XRES            0x1
 | 
			
		||||
#define VBE_DISPI_INDEX_YRES            0x2
 | 
			
		||||
#define VBE_DISPI_INDEX_BPP             0x3
 | 
			
		||||
#define VBE_DISPI_INDEX_ENABLE          0x4
 | 
			
		||||
#define VBE_DISPI_INDEX_BANK            0x5
 | 
			
		||||
#define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
 | 
			
		||||
#define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
 | 
			
		||||
#define VBE_DISPI_INDEX_X_OFFSET        0x8
 | 
			
		||||
#define VBE_DISPI_INDEX_Y_OFFSET        0x9
 | 
			
		||||
 | 
			
		||||
/* BGA Version */
 | 
			
		||||
#define VBE_DISPI_ID5   0xB0C5
 | 
			
		||||
#define VBE_DISPI_ID4   0xB0C3 
 | 
			
		||||
#define VBE_DISPI_ID3   0xB0C2
 | 
			
		||||
#define VBE_DISPI_ID2   0xB0C1
 | 
			
		||||
#define VBE_DISPI_ID1   0xB0C0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* BGA BIT DEPTH */
 | 
			
		||||
#define VBE_DISPI_BPP_4 0x04
 | 
			
		||||
#define VBE_DISPI_BPP_8 0x08
 | 
			
		||||
#define VBE_DISPI_BPP_15 0x0F
 | 
			
		||||
#define VBE_DISPI_BPP_16 0x10
 | 
			
		||||
#define VBE_DISPI_BPP_24 0x18
 | 
			
		||||
#define VBE_DISPI_BPP_32 0x20
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /*unsigned short BGAReadRegister(unsigned short IndexValue){
 | 
			
		||||
        // outpw(VBE_DISPI_IOPORT_INDEX, IndexValue);
 | 
			
		||||
       // return inpw (VBE_DISPI_IOPORT_DATA);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int BGAIsAvailable (){
 | 
			
		||||
        return (BGAReadRegister(VBE_DISPI_INDEX_ID) == VBE_DISPI_ID5);
 | 
			
		||||
    }*/
 | 
			
		||||
							
								
								
									
										73
									
								
								src/kernel/bootcheck.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/kernel/bootcheck.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "bootloader/multiboot.h"
 | 
			
		||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
    #include "arch/i386/tty/kterm.h"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void CheckMBT ( multiboot_info_t*  mbt  ){
 | 
			
		||||
      /* Set MBI to the addresss of the multiboot information structure*/
 | 
			
		||||
        multiboot_info_t * mbi = (multiboot_info_t *) mbt;
 | 
			
		||||
 | 
			
		||||
        /* Print out the flags */
 | 
			
		||||
        printf("flags = 0x%x\n", (unsigned) mbi->flags);
 | 
			
		||||
 | 
			
		||||
        /* Are mem_* valid? */
 | 
			
		||||
        if ( CHECK_FLAG(mbi->flags,0)){
 | 
			
		||||
            printf("mem_lower = %uKB, mem_upper = %uKB\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* is boot device valid ? */
 | 
			
		||||
        if (CHECK_FLAG (mbi->flags, 1)){
 | 
			
		||||
            printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* is the command line passed? */
 | 
			
		||||
        if (CHECK_FLAG ( mbi->flags,2)){
 | 
			
		||||
            printf("cmdline = %s\n", (char *) mbi->cmdline);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Are mods_* valid? */
 | 
			
		||||
        if(CHECK_FLAG ( mbi->flags, 3)){
 | 
			
		||||
            multiboot_module_t *mod;
 | 
			
		||||
            uint32_t i;
 | 
			
		||||
 | 
			
		||||
            printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
 | 
			
		||||
 | 
			
		||||
            for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
 | 
			
		||||
                printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Bits 4 and 5 are mutually exclusive! */
 | 
			
		||||
        if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){
 | 
			
		||||
            printf("Both bits 4 and 5 are set.\n");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Is the symbol table of a.out valid? */
 | 
			
		||||
        if (CHECK_FLAG(mbi->flags, 4)){
 | 
			
		||||
            multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
 | 
			
		||||
 | 
			
		||||
            printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", 
 | 
			
		||||
            (unsigned) multiboot_aout_sym->tabsize,
 | 
			
		||||
            (unsigned) multiboot_aout_sym->strsize,
 | 
			
		||||
            (unsigned) multiboot_aout_sym->addr);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Is the section header table of ELF valid? */
 | 
			
		||||
        if (CHECK_FLAG(mbi->flags, 5)){
 | 
			
		||||
            multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
 | 
			
		||||
 | 
			
		||||
            printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n",
 | 
			
		||||
            (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
 | 
			
		||||
            (unsigned) multiboot_elf_sec->addr, (unsigned)  multiboot_elf_sec->shndx);
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										274
									
								
								src/kernel/bootloader/multiboot.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								src/kernel/bootloader/multiboot.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,274 @@
 | 
			
		||||
/* multiboot.h - Multiboot header file. */
 | 
			
		||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 *  of this software and associated documentation files (the "Software"), to
 | 
			
		||||
 *  deal in the Software without restriction, including without limitation the
 | 
			
		||||
 *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 | 
			
		||||
 *  sell copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 *  furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 *  The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 *  all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
 | 
			
		||||
 *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
			
		||||
 *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 | 
			
		||||
 *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MULTIBOOT_HEADER
 | 
			
		||||
#define MULTIBOOT_HEADER 1
 | 
			
		||||
 | 
			
		||||
/* How many bytes from the start of the file we search for the header. */
 | 
			
		||||
#define MULTIBOOT_SEARCH                        8192
 | 
			
		||||
#define MULTIBOOT_HEADER_ALIGN                  4
 | 
			
		||||
 | 
			
		||||
/* The magic field should contain this. */
 | 
			
		||||
#define MULTIBOOT_HEADER_MAGIC                  0x1BADB002
 | 
			
		||||
 | 
			
		||||
/* This should be in %eax. */
 | 
			
		||||
#define MULTIBOOT_BOOTLOADER_MAGIC              0x2BADB002
 | 
			
		||||
 | 
			
		||||
/* Alignment of multiboot modules. */
 | 
			
		||||
#define MULTIBOOT_MOD_ALIGN                     0x00001000
 | 
			
		||||
 | 
			
		||||
/* Alignment of the multiboot info structure. */
 | 
			
		||||
#define MULTIBOOT_INFO_ALIGN                    0x00000004
 | 
			
		||||
 | 
			
		||||
/* Flags set in the ’flags’ member of the multiboot header. */
 | 
			
		||||
 | 
			
		||||
/* Align all boot modules on i386 page (4KB) boundaries. */
 | 
			
		||||
#define MULTIBOOT_PAGE_ALIGN                    0x00000001
 | 
			
		||||
 | 
			
		||||
/* Must pass memory information to OS. */
 | 
			
		||||
#define MULTIBOOT_MEMORY_INFO                   0x00000002
 | 
			
		||||
 | 
			
		||||
/* Must pass video information to OS. */
 | 
			
		||||
#define MULTIBOOT_VIDEO_MODE                    0x00000004
 | 
			
		||||
 | 
			
		||||
/* This flag indicates the use of the address fields in the header. */
 | 
			
		||||
#define MULTIBOOT_AOUT_KLUDGE                   0x00010000
 | 
			
		||||
 | 
			
		||||
/* Flags to be set in the ’flags’ member of the multiboot info structure. */
 | 
			
		||||
 | 
			
		||||
/* is there basic lower/upper memory information? */
 | 
			
		||||
#define MULTIBOOT_INFO_MEMORY                   0x00000001
 | 
			
		||||
/* is there a boot device set? */
 | 
			
		||||
#define MULTIBOOT_INFO_BOOTDEV                  0x00000002
 | 
			
		||||
/* is the command-line defined? */
 | 
			
		||||
#define MULTIBOOT_INFO_CMDLINE                  0x00000004
 | 
			
		||||
/* are there modules to do something with? */
 | 
			
		||||
#define MULTIBOOT_INFO_MODS                     0x00000008
 | 
			
		||||
 | 
			
		||||
/* These next two are mutually exclusive */
 | 
			
		||||
 | 
			
		||||
/* is there a symbol table loaded? */
 | 
			
		||||
#define MULTIBOOT_INFO_AOUT_SYMS                0x00000010
 | 
			
		||||
/* is there an ELF section header table? */
 | 
			
		||||
#define MULTIBOOT_INFO_ELF_SHDR                 0X00000020
 | 
			
		||||
 | 
			
		||||
/* is there a full memory map? */
 | 
			
		||||
#define MULTIBOOT_INFO_MEM_MAP                  0x00000040
 | 
			
		||||
 | 
			
		||||
/* Is there drive info? */
 | 
			
		||||
#define MULTIBOOT_INFO_DRIVE_INFO               0x00000080
 | 
			
		||||
 | 
			
		||||
/* Is there a config table? */
 | 
			
		||||
#define MULTIBOOT_INFO_CONFIG_TABLE             0x00000100
 | 
			
		||||
 | 
			
		||||
/* Is there a boot loader name? */
 | 
			
		||||
#define MULTIBOOT_INFO_BOOT_LOADER_NAME         0x00000200
 | 
			
		||||
 | 
			
		||||
/* Is there a APM table? */
 | 
			
		||||
#define MULTIBOOT_INFO_APM_TABLE                0x00000400
 | 
			
		||||
 | 
			
		||||
/* Is there video information? */
 | 
			
		||||
#define MULTIBOOT_INFO_VBE_INFO                 0x00000800
 | 
			
		||||
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO         0x00001000
 | 
			
		||||
 | 
			
		||||
#ifndef ASM_FILE
 | 
			
		||||
 | 
			
		||||
typedef unsigned char           multiboot_uint8_t;
 | 
			
		||||
typedef unsigned short          multiboot_uint16_t;
 | 
			
		||||
typedef unsigned int            multiboot_uint32_t;
 | 
			
		||||
typedef unsigned long long      multiboot_uint64_t;
 | 
			
		||||
 | 
			
		||||
struct multiboot_header
 | 
			
		||||
{
 | 
			
		||||
  /* Must be MULTIBOOT_MAGIC - see above. */
 | 
			
		||||
  multiboot_uint32_t magic;
 | 
			
		||||
 | 
			
		||||
  /* Feature flags. */
 | 
			
		||||
  multiboot_uint32_t flags;
 | 
			
		||||
 | 
			
		||||
  /* The above fields plus this one must equal 0 mod 2^32. */
 | 
			
		||||
  multiboot_uint32_t checksum;
 | 
			
		||||
 | 
			
		||||
  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
 | 
			
		||||
  multiboot_uint32_t header_addr;
 | 
			
		||||
  multiboot_uint32_t load_addr;
 | 
			
		||||
  multiboot_uint32_t load_end_addr;
 | 
			
		||||
  multiboot_uint32_t bss_end_addr;
 | 
			
		||||
  multiboot_uint32_t entry_addr;
 | 
			
		||||
 | 
			
		||||
  /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
 | 
			
		||||
  multiboot_uint32_t mode_type;
 | 
			
		||||
  multiboot_uint32_t width;
 | 
			
		||||
  multiboot_uint32_t height;
 | 
			
		||||
  multiboot_uint32_t depth;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* The symbol table for a.out. */
 | 
			
		||||
struct multiboot_aout_symbol_table
 | 
			
		||||
{
 | 
			
		||||
  multiboot_uint32_t tabsize;
 | 
			
		||||
  multiboot_uint32_t strsize;
 | 
			
		||||
  multiboot_uint32_t addr;
 | 
			
		||||
  multiboot_uint32_t reserved;
 | 
			
		||||
};
 | 
			
		||||
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
 | 
			
		||||
 | 
			
		||||
/* The section header table for ELF. */
 | 
			
		||||
struct multiboot_elf_section_header_table
 | 
			
		||||
{
 | 
			
		||||
  multiboot_uint32_t num;
 | 
			
		||||
  multiboot_uint32_t size;
 | 
			
		||||
  multiboot_uint32_t addr;
 | 
			
		||||
  multiboot_uint32_t shndx;
 | 
			
		||||
};
 | 
			
		||||
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
 | 
			
		||||
 | 
			
		||||
struct multiboot_info
 | 
			
		||||
{
 | 
			
		||||
  /* Multiboot info version number */
 | 
			
		||||
  multiboot_uint32_t flags;
 | 
			
		||||
 | 
			
		||||
  /* Available memory from BIOS */
 | 
			
		||||
  multiboot_uint32_t mem_lower;
 | 
			
		||||
  multiboot_uint32_t mem_upper;
 | 
			
		||||
 | 
			
		||||
  /* "root" partition */
 | 
			
		||||
  multiboot_uint32_t boot_device;
 | 
			
		||||
 | 
			
		||||
  /* Kernel command line */
 | 
			
		||||
  multiboot_uint32_t cmdline;
 | 
			
		||||
 | 
			
		||||
  /* Boot-Module list */
 | 
			
		||||
  multiboot_uint32_t mods_count;
 | 
			
		||||
  multiboot_uint32_t mods_addr;
 | 
			
		||||
 | 
			
		||||
  union
 | 
			
		||||
  {
 | 
			
		||||
    multiboot_aout_symbol_table_t aout_sym;
 | 
			
		||||
    multiboot_elf_section_header_table_t elf_sec;
 | 
			
		||||
  } u;
 | 
			
		||||
 | 
			
		||||
  /* Memory Mapping buffer */
 | 
			
		||||
  multiboot_uint32_t mmap_length;
 | 
			
		||||
  multiboot_uint32_t mmap_addr;
 | 
			
		||||
 | 
			
		||||
  /* Drive Info buffer */
 | 
			
		||||
  multiboot_uint32_t drives_length;
 | 
			
		||||
  multiboot_uint32_t drives_addr;
 | 
			
		||||
 | 
			
		||||
  /* ROM configuration table */
 | 
			
		||||
  multiboot_uint32_t config_table;
 | 
			
		||||
 | 
			
		||||
  /* Boot Loader Name */
 | 
			
		||||
  multiboot_uint32_t boot_loader_name;
 | 
			
		||||
 | 
			
		||||
  /* APM table */
 | 
			
		||||
  multiboot_uint32_t apm_table;
 | 
			
		||||
 | 
			
		||||
  /* Video */
 | 
			
		||||
  multiboot_uint32_t vbe_control_info;
 | 
			
		||||
  multiboot_uint32_t vbe_mode_info;
 | 
			
		||||
  multiboot_uint16_t vbe_mode;
 | 
			
		||||
  multiboot_uint16_t vbe_interface_seg;
 | 
			
		||||
  multiboot_uint16_t vbe_interface_off;
 | 
			
		||||
  multiboot_uint16_t vbe_interface_len;
 | 
			
		||||
 | 
			
		||||
  multiboot_uint64_t framebuffer_addr;
 | 
			
		||||
  multiboot_uint32_t framebuffer_pitch;
 | 
			
		||||
  multiboot_uint32_t framebuffer_width;
 | 
			
		||||
  multiboot_uint32_t framebuffer_height;
 | 
			
		||||
  multiboot_uint8_t framebuffer_bpp;
 | 
			
		||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
 | 
			
		||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
 | 
			
		||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT     2
 | 
			
		||||
  multiboot_uint8_t framebuffer_type;
 | 
			
		||||
  union
 | 
			
		||||
  {
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
      multiboot_uint32_t framebuffer_palette_addr;
 | 
			
		||||
      multiboot_uint16_t framebuffer_palette_num_colors;
 | 
			
		||||
    };
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
      multiboot_uint8_t framebuffer_red_field_position;
 | 
			
		||||
      multiboot_uint8_t framebuffer_red_mask_size;
 | 
			
		||||
      multiboot_uint8_t framebuffer_green_field_position;
 | 
			
		||||
      multiboot_uint8_t framebuffer_green_mask_size;
 | 
			
		||||
      multiboot_uint8_t framebuffer_blue_field_position;
 | 
			
		||||
      multiboot_uint8_t framebuffer_blue_mask_size;
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
typedef struct multiboot_info multiboot_info_t;
 | 
			
		||||
 | 
			
		||||
struct multiboot_color
 | 
			
		||||
{
 | 
			
		||||
  multiboot_uint8_t red;
 | 
			
		||||
  multiboot_uint8_t green;
 | 
			
		||||
  multiboot_uint8_t blue;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct multiboot_mmap_entry
 | 
			
		||||
{
 | 
			
		||||
  multiboot_uint32_t size;
 | 
			
		||||
  multiboot_uint64_t addr;
 | 
			
		||||
  multiboot_uint64_t len;
 | 
			
		||||
#define MULTIBOOT_MEMORY_AVAILABLE              1
 | 
			
		||||
#define MULTIBOOT_MEMORY_RESERVED               2
 | 
			
		||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
 | 
			
		||||
#define MULTIBOOT_MEMORY_NVS                    4
 | 
			
		||||
#define MULTIBOOT_MEMORY_BADRAM                 5
 | 
			
		||||
  multiboot_uint32_t type;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
 | 
			
		||||
 | 
			
		||||
struct multiboot_mod_list
 | 
			
		||||
{
 | 
			
		||||
  /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */
 | 
			
		||||
  multiboot_uint32_t mod_start;
 | 
			
		||||
  multiboot_uint32_t mod_end;
 | 
			
		||||
 | 
			
		||||
  /* Module command line */
 | 
			
		||||
  multiboot_uint32_t cmdline;
 | 
			
		||||
 | 
			
		||||
  /* padding to take it to 16 bytes (must be zero) */
 | 
			
		||||
  multiboot_uint32_t pad;
 | 
			
		||||
};
 | 
			
		||||
typedef struct multiboot_mod_list multiboot_module_t;
 | 
			
		||||
 | 
			
		||||
/* APM BIOS info. */
 | 
			
		||||
struct multiboot_apm_info
 | 
			
		||||
{
 | 
			
		||||
  multiboot_uint16_t version;
 | 
			
		||||
  multiboot_uint16_t cseg;
 | 
			
		||||
  multiboot_uint32_t offset;
 | 
			
		||||
  multiboot_uint16_t cseg_16;
 | 
			
		||||
  multiboot_uint16_t dseg;
 | 
			
		||||
  multiboot_uint16_t flags;
 | 
			
		||||
  multiboot_uint16_t cseg_len;
 | 
			
		||||
  multiboot_uint16_t cseg_16_len;
 | 
			
		||||
  multiboot_uint16_t dseg_len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* ! ASM_FILE */
 | 
			
		||||
 | 
			
		||||
#endif /* ! MULTIBOOT_HEADER */
 | 
			
		||||
							
								
								
									
										17
									
								
								src/kernel/cpu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/kernel/cpu.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#include <cpuid.h> // NOTE: Only available in GCC 
 | 
			
		||||
// NOT currently usefull!
 | 
			
		||||
/*    static int get_model(){
 | 
			
		||||
        int ebx, unused;
 | 
			
		||||
        __cpuid(0, unused, ebx, unused, unused);
 | 
			
		||||
        return ebx;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum {
 | 
			
		||||
        CPUID_FEAT_EDX_APIC = 1 << 9
 | 
			
		||||
    };
 | 
			
		||||
    static int check_apic (){
 | 
			
		||||
        unsigned int eax, unused, edx;
 | 
			
		||||
        __get_cpuid(1, &eax, &unused, &unused, &edx);
 | 
			
		||||
        return  edx & CPUID_FEAT_EDX_APIC;
 | 
			
		||||
    }
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										17
									
								
								src/kernel/disk.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/kernel/disk.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Let's write an ATA PIO | ATA driver for now. Mostly to show that I can in theory interact with a
 | 
			
		||||
// storage device
 | 
			
		||||
 | 
			
		||||
// PRIMARY_ATA_BUS
 | 
			
		||||
// 0x1F0 through 0x1F7 
 | 
			
		||||
 | 
			
		||||
// SECONDARY_ATA_BUS
 | 
			
		||||
// 0x170 through 0x177
 | 
			
		||||
 | 
			
		||||
#define DEVICE_CONTROL_REGISTER 0x3F6
 | 
			
		||||
#define DEVICE_CONTROL_ALTERNATE 0x376
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// IRQ14 Primary bus interrupt
 | 
			
		||||
// IRQ15 Secondary bus interrupt
 | 
			
		||||
@ -1,19 +1,24 @@
 | 
			
		||||
#include "io.h"
 | 
			
		||||
 | 
			
		||||
unsigned char inb_p(unsigned short ){
 | 
			
		||||
 | 
			
		||||
        // TODO: implement me!
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
unsigned short inw(unsigned short ){
 | 
			
		||||
 | 
			
		||||
// TODO: implement me!
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
unsigned short inw_p(unsigned short ){
 | 
			
		||||
 | 
			
		||||
// TODO: implement me!
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
unsigned int inl(unsigned short ){
 | 
			
		||||
 | 
			
		||||
// TODO: implement me!
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
unsigned int inl_p(unsigned short ){
 | 
			
		||||
 | 
			
		||||
// TODO: implement me!
 | 
			
		||||
        return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,164 +1,91 @@
 | 
			
		||||
#include "kernel.h"
 | 
			
		||||
/**
 | 
			
		||||
 *      simple delay function 
 | 
			
		||||
 **/
 | 
			
		||||
void delay(int t){
 | 
			
		||||
    volatile int i,j;
 | 
			
		||||
    for(i=0;i<t;i++)
 | 
			
		||||
        for(j=0;j<25000;j++)
 | 
			
		||||
            asm("NOP");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Test {
 | 
			
		||||
    public:
 | 
			
		||||
         Test();
 | 
			
		||||
        void printMe();
 | 
			
		||||
         ~Test();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Test::Test(){
 | 
			
		||||
    kterm_writestring("Create a test object\n");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void Test::printMe(){
 | 
			
		||||
    kterm_writestring("testObject.printMe()\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Test::~Test(){
 | 
			
		||||
    kterm_writestring("Destroy testObject! Bye bye\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define PORT 0x3f8 
 | 
			
		||||
static int init_serial() {
 | 
			
		||||
   outb(PORT + 1, 0x00);    // Disable all interrupts
 | 
			
		||||
   outb(PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
 | 
			
		||||
   outb(PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
 | 
			
		||||
   outb(PORT + 1, 0x00);    //                  (hi byte)
 | 
			
		||||
   outb(PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
 | 
			
		||||
   outb(PORT + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
 | 
			
		||||
   outb(PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
 | 
			
		||||
   outb(PORT + 4, 0x1E);    // Set in loopback mode, test the serial chip
 | 
			
		||||
   outb(PORT + 0, 0xAE);    // Test serial chip (send byte 0xAE and check if serial returns same byte)
 | 
			
		||||
 
 | 
			
		||||
   // Check if serial is faulty (i.e: not same byte as sent)
 | 
			
		||||
   if(inb(PORT + 0) != 0xAE) {
 | 
			
		||||
      return 1;
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
   // If serial is not faulty set it in normal operation mode
 | 
			
		||||
   // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
 | 
			
		||||
   outb(PORT + 4, 0x0F);
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int is_transmit_empty() {
 | 
			
		||||
   return inb(PORT + 5) & 0x20;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void write_serial(char a) {
 | 
			
		||||
   while (is_transmit_empty() == 0);
 | 
			
		||||
 
 | 
			
		||||
   outb(PORT,a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int serial_received() {
 | 
			
		||||
   return inb(PORT + 5) & 1;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
char read_serial() {
 | 
			
		||||
   while (serial_received() == 0);
 | 
			
		||||
 
 | 
			
		||||
   return inb(PORT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_serial(const char* string ){
 | 
			
		||||
    for(size_t i = 0; i < strlen(string); i ++){
 | 
			
		||||
        write_serial(string[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_serial(){
 | 
			
		||||
        /** Serial test **/
 | 
			
		||||
        kterm_writestring("Writing to COM1 serial port:");
 | 
			
		||||
        init_serial();
 | 
			
		||||
        write_serial('A');
 | 
			
		||||
        write_serial('B');
 | 
			
		||||
        write_serial('C');
 | 
			
		||||
        write_serial('D');
 | 
			
		||||
        write_serial('E');
 | 
			
		||||
 | 
			
		||||
        char Character_received = read_serial();
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
        kterm_writestring("received from COM 1: \n");
 | 
			
		||||
        kterm_put(Character_received);
 | 
			
		||||
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "arch/i386/gdt/gdtc.h"
 | 
			
		||||
extern "C" {
 | 
			
		||||
 | 
			
		||||
    void early_main(){
 | 
			
		||||
    void early_main(unsigned long magic, unsigned long addr){
 | 
			
		||||
        /** initialize terminal interface */ 
 | 
			
		||||
        kterm_init();
 | 
			
		||||
        
 | 
			
		||||
        if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
 | 
			
		||||
            printf("Invalid magic number: 0x%x\n",  magic);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
       init_serial();
 | 
			
		||||
       print_serial("\033[31;42mEarly main called!\n");
 | 
			
		||||
   
 | 
			
		||||
        CheckMBT(  (multiboot_info_t *) addr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        multiboot_info_t* mbt = (multiboot_info_t*) addr;
 | 
			
		||||
 | 
			
		||||
        // Map the kernel
 | 
			
		||||
        //initPhysicalMemoryManager();
 | 
			
		||||
 | 
			
		||||
        // AAAAAH memory map, Yes please!
 | 
			
		||||
        /* Are mmap_* valid? */
 | 
			
		||||
        if (CHECK_FLAG(mbt->flags, 6)){
 | 
			
		||||
            multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
 | 
			
		||||
            uint32_t memorySizeInBytes = 0;
 | 
			
		||||
            uint32_t reservedMemoryInBytes = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            printf("mmap_addr = 0x%x, mmap_length = 0x%x\n",
 | 
			
		||||
            (unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length);
 | 
			
		||||
            
 | 
			
		||||
            for (;  (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length;  mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
 | 
			
		||||
                    if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
 | 
			
		||||
                        memorySizeInBytes +=  mmap->len;   
 | 
			
		||||
                    } else {
 | 
			
		||||
                        reservedMemoryInBytes += mmap->len;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    printf(
 | 
			
		||||
                        "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
 | 
			
		||||
                        (unsigned) mmap->size,
 | 
			
		||||
                        (unsigned) (mmap->addr >> 32),
 | 
			
		||||
                        (unsigned) (mmap->addr & 0xffffffff),
 | 
			
		||||
                        (unsigned) (mmap->len >> 32),
 | 
			
		||||
                        (unsigned) (mmap->len & 0xffffffff),
 | 
			
		||||
                        (unsigned) mmap->type);
 | 
			
		||||
                
 | 
			
		||||
                }
 | 
			
		||||
            uint32_t memorySizeInGiB = memorySizeInBytes / 1073741824; 
 | 
			
		||||
            
 | 
			
		||||
            printf("Available Memory: 0x%x bytes, 0x%x GiB\n",  memorySizeInBytes, memorySizeInGiB );
 | 
			
		||||
            printf("Reserved Memory: 0x%x bytes\n",  reservedMemoryInBytes );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
       //int cpu_model = get_model();
 | 
			
		||||
       //int local_apic = check_apic();
 | 
			
		||||
       //printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
     /* Setup Paging and memory Managment*/
 | 
			
		||||
        //MMU  MemoryManagementUnit = MMU();
 | 
			
		||||
        //MemoryManagementUnit.enable(); // Warning: Causes triple page fault
 | 
			
		||||
        //printf("Pages available: %9d\n", pmm_available());
 | 
			
		||||
 | 
			
		||||
        /* Draw diagonal blue line */
 | 
			
		||||
        if (CHECK_FLAG (mbt->flags, 12)){
 | 
			
		||||
            printf("Can draw!");
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        //setupGdt();
 | 
			
		||||
 | 
			
		||||
       
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void kernel_main (void) {
 | 
			
		||||
       
 | 
			
		||||
        print_serial("Kernel main called!\n");
 | 
			
		||||
 | 
			
		||||
        init_serial();
 | 
			
		||||
 | 
			
		||||
        /** initialize terminal interface */ 
 | 
			
		||||
        kterm_init();
 | 
			
		||||
 | 
			
		||||
        /** Setup the MMU **/
 | 
			
		||||
        //kterm_writestring("Starting MMU...\n");
 | 
			
		||||
        //auto mmu = MMU();
 | 
			
		||||
        //mmu.enable();
 | 
			
		||||
        //kterm_writestring("MMU enabled!\n");
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /** Wrtite stuff to the screen to test the terminal**/ 
 | 
			
		||||
        kterm_writestring("Hello world!\n");
 | 
			
		||||
        kterm_writestring("We got newline support!\n");
 | 
			
		||||
 | 
			
		||||
        /** Test scrolling **/
 | 
			
		||||
        for(int i=0; i < 5; i++){
 | 
			
		||||
            delay(500);
 | 
			
		||||
            kterm_writestring("We have implemented terminal scrolling!\n");
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
        /** Test objective cpp **/
 | 
			
		||||
        kterm_writestring("Testing C++ object support\n");
 | 
			
		||||
        auto testObject = Test();
 | 
			
		||||
        testObject.printMe();
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        /** test interrupt handlers **/
 | 
			
		||||
        //asm volatile ("int $0x03");
 | 
			
		||||
 | 
			
		||||
        //asm volatile ("int $0x04");
 | 
			
		||||
 | 
			
		||||
        while (true){
 | 
			
		||||
        while (false){
 | 
			
		||||
            //Read time indefinetely 
 | 
			
		||||
            read_rtc();
 | 
			
		||||
            printf( "UTC time: %2d-%2d-%2d %2d:%2d:%2d  : (YY-MM-DD h:mm:ss)\r" ,year, month, day, hour, minute, second);
 | 
			
		||||
            printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d  [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second);
 | 
			
		||||
            delay(1000);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /** Lets start using the serial port for debugging .. **/
 | 
			
		||||
        // Hopefully once we go into realmode or do something that
 | 
			
		||||
        // cause the screen to go black.. this serial comms part will give
 | 
			
		||||
        // some situational awareness
 | 
			
		||||
        //Serial serialbus = Serial::init();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
       
 | 
			
		||||
    }   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,114 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
extern "C" {
 | 
			
		||||
    #include "../libc/include/string.h"
 | 
			
		||||
    #include "arch/i386/tty/kterm.h"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "../libc/include/string.h"
 | 
			
		||||
#include "./bootloader/multiboot.h"
 | 
			
		||||
#include "bootcheck.h"
 | 
			
		||||
#include "arch/i386/idt/idt.h"
 | 
			
		||||
#include "MMU.h"
 | 
			
		||||
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "time.h"
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
#include "arch/i386/vga/VBE.h"
 | 
			
		||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This needs to be moved! */
 | 
			
		||||
/**
 | 
			
		||||
 *      simple delay function 
 | 
			
		||||
 **/
 | 
			
		||||
void delay(int t){
 | 
			
		||||
    volatile int i,j;
 | 
			
		||||
    for(i=0;i<t;i++)
 | 
			
		||||
        for(j=0;j<25000;j++)
 | 
			
		||||
            asm("NOP");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Test {
 | 
			
		||||
    public:
 | 
			
		||||
         Test();
 | 
			
		||||
        void printMe();
 | 
			
		||||
         ~Test();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Test::Test(){
 | 
			
		||||
    kterm_writestring("Create a test object\n");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void Test::printMe(){
 | 
			
		||||
    kterm_writestring("testObject.printMe()\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Test::~Test(){
 | 
			
		||||
    kterm_writestring("Destroy testObject! Bye bye\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define PORT 0x3f8 
 | 
			
		||||
static int init_serial() {
 | 
			
		||||
   outb(PORT + 1, 0x00);    // Disable all interrupts
 | 
			
		||||
   outb(PORT + 3, 0x80);    // Enable DLAB (set baud rate divisor)
 | 
			
		||||
   outb(PORT + 0, 0x03);    // Set divisor to 3 (lo byte) 38400 baud
 | 
			
		||||
   outb(PORT + 1, 0x00);    //                  (hi byte)
 | 
			
		||||
   outb(PORT + 3, 0x03);    // 8 bits, no parity, one stop bit
 | 
			
		||||
   outb(PORT + 2, 0xC7);    // Enable FIFO, clear them, with 14-byte threshold
 | 
			
		||||
   outb(PORT + 4, 0x0B);    // IRQs enabled, RTS/DSR set
 | 
			
		||||
   outb(PORT + 4, 0x1E);    // Set in loopback mode, test the serial chip
 | 
			
		||||
   outb(PORT + 0, 0xAE);    // Test serial chip (send byte 0xAE and check if serial returns same byte)
 | 
			
		||||
 
 | 
			
		||||
   // Check if serial is faulty (i.e: not same byte as sent)
 | 
			
		||||
   if(inb(PORT + 0) != 0xAE) {
 | 
			
		||||
      return 1;
 | 
			
		||||
   }
 | 
			
		||||
 
 | 
			
		||||
   // If serial is not faulty set it in normal operation mode
 | 
			
		||||
   // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
 | 
			
		||||
   outb(PORT + 4, 0x0F);
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int is_transmit_empty() {
 | 
			
		||||
   return inb(PORT + 5) & 0x20;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void write_serial(char a) {
 | 
			
		||||
   while (is_transmit_empty() == 0);
 | 
			
		||||
 
 | 
			
		||||
   outb(PORT,a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int serial_received() {
 | 
			
		||||
   return inb(PORT + 5) & 1;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
char read_serial() {
 | 
			
		||||
   while (serial_received() == 0);
 | 
			
		||||
 
 | 
			
		||||
   return inb(PORT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_serial(const char* string ){
 | 
			
		||||
    for(size_t i = 0; i < strlen(string); i ++){
 | 
			
		||||
        write_serial(string[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_serial(){
 | 
			
		||||
        /** Serial test **/
 | 
			
		||||
        kterm_writestring("Writing to COM1 serial port:");
 | 
			
		||||
        init_serial();
 | 
			
		||||
        write_serial('A');
 | 
			
		||||
        write_serial('B');
 | 
			
		||||
        write_serial('C');
 | 
			
		||||
        write_serial('D');
 | 
			
		||||
        write_serial('E');
 | 
			
		||||
 | 
			
		||||
        char Character_received = read_serial();
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
        kterm_writestring("received from COM 1: \n");
 | 
			
		||||
        kterm_put(Character_received);
 | 
			
		||||
 | 
			
		||||
        kterm_writestring("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,9 @@
 | 
			
		||||
#include "MMU.h"
 | 
			
		||||
#include "PageDirectory.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void MMU::enable(){
 | 
			
		||||
void PageDirectory::enable(){
 | 
			
		||||
 | 
			
		||||
    //set each entry to not present
 | 
			
		||||
    int i;
 | 
			
		||||
@ -21,9 +22,9 @@ void MMU::enable(){
 | 
			
		||||
    //we will fill all 1024 entries in the table, mapping 4 megabytes
 | 
			
		||||
    for(unsigned int i = 0; i < 1024; i++)
 | 
			
		||||
    {
 | 
			
		||||
    // As the address is page aligned, it will always leave 12 bits zeroed.
 | 
			
		||||
    // Those bits are used by the attributes ;)
 | 
			
		||||
    first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
 | 
			
		||||
        // As the address is page aligned, it will always leave 12 bits zeroed.
 | 
			
		||||
        // Those bits are used by the attributes ;)
 | 
			
		||||
        first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // attributes: supervisor level, read/write, present
 | 
			
		||||
@ -32,4 +33,15 @@ void MMU::enable(){
 | 
			
		||||
 | 
			
		||||
    loadPageDirectory(this->page_directory);
 | 
			
		||||
    enablePaging();
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
void IdentityPaging(uint32_t *first_pte, vaddr from, int size)
 | 
			
		||||
{
 | 
			
		||||
    from = from & 0xFFFFF000; // Discard the bits we don't want
 | 
			
		||||
    for (; size > 0; from += 4096, first_pte++)
 | 
			
		||||
    {
 | 
			
		||||
        *first_pte = from | 1; // makr page present.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										28
									
								
								src/kernel/memory/PageDirectory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/kernel/memory/PageDirectory.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
extern "C" void loadPageDirectory (uint32_t* addr );
 | 
			
		||||
extern "C" void enablePaging();
 | 
			
		||||
typedef uintptr_t address_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define KB 1024
 | 
			
		||||
 | 
			
		||||
static const int MAX_PAGES =  1024 * KB; // 4GB , 4kB/page
 | 
			
		||||
static volatile address_t pmem_stack[MAX_PAGES];
 | 
			
		||||
static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct page_directory_entry {};
 | 
			
		||||
struct page_table_entry{};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PageDirectory {
 | 
			
		||||
    public:
 | 
			
		||||
    void enable ();
 | 
			
		||||
    
 | 
			
		||||
    private:
 | 
			
		||||
    uint32_t page_directory[1024] __attribute__((aligned(4096)));
 | 
			
		||||
    uint32_t first_page_table[1024] __attribute__((aligned(4096)));
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1
									
								
								src/kernel/memory/PageFramAllocator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/kernel/memory/PageFramAllocator.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
#include "PageFrameAllocator.h"
 | 
			
		||||
							
								
								
									
										8
									
								
								src/kernel/memory/PageFrameAllocator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/kernel/memory/PageFrameAllocator.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void *kernel_begin;
 | 
			
		||||
extern void *kernel_end;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								src/kernel/memory/SlabAllocator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/kernel/memory/SlabAllocator.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
/**
 | 
			
		||||
 *  We'll need something to this effect to allocate memory in the kernel
 | 
			
		||||
 *  this will hopefully someday implement a full slab allocator 
 | 
			
		||||
 **/
 | 
			
		||||
enum SlabState {
 | 
			
		||||
    empty,
 | 
			
		||||
    partial,
 | 
			
		||||
    full 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class CacheSlab {
 | 
			
		||||
    const int SlabSize = 4000;
 | 
			
		||||
    void* start = 0x0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Allocator {
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        Allocator();
 | 
			
		||||
        ~Allocator();
 | 
			
		||||
 | 
			
		||||
        void* kmalloc( int size );
 | 
			
		||||
        void kfree (void* address);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        CacheSlab** _cache;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										108
									
								
								src/kernel/pci.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/kernel/pci.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,108 @@
 | 
			
		||||
#include "pci.h"
 | 
			
		||||
 | 
			
		||||
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset){
 | 
			
		||||
    uint32_t address;
 | 
			
		||||
    uint32_t lbus = (uint32_t) bus;
 | 
			
		||||
    uint32_t lslot = (uint32_t) slot;
 | 
			
		||||
    uint32_t lfunc = (uint32_t) func;
 | 
			
		||||
    uint16_t tmp = 0;
 | 
			
		||||
 | 
			
		||||
    /* Create configuration address as per Figure 1 */
 | 
			
		||||
    address = (uint32_t) ((lbus << 16) |  (lslot << 11) | (lfunc << 8) | (offset & 0xFC) |((uint32_t) 0x80000000) );
 | 
			
		||||
    /*write out the address */ 
 | 
			
		||||
    outl(CONFIG_ADDRESS, address);
 | 
			
		||||
    /* read in the data */
 | 
			
		||||
    /* (offset & 2 ) * 8 ) = o will choosse the first word of the 32 bits register*/
 | 
			
		||||
    tmp = (uint16_t)((inl(CONFIG_DATA)) >> ((offset & 2) * 8) & 0xFFFF);
 | 
			
		||||
    return (tmp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t CheckVendor (uint8_t bus, uint8_t slot) {
 | 
			
		||||
    uint16_t vendor, device;
 | 
			
		||||
    /* 
 | 
			
		||||
        Try and read the first configuration register. Since there ar no
 | 
			
		||||
        vendors that == 0xFFFF, it must be a non-existent device.
 | 
			
		||||
    */
 | 
			
		||||
   if((vendor = ConfigReadWord(bus, slot, 0,0)) != 0xFFFF) {
 | 
			
		||||
       device = ConfigReadWord(bus, slot, 0,2);
 | 
			
		||||
        // Possible read more config values ...
 | 
			
		||||
   } return (vendor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void checkDevice (uint8_t bus, uint8_t device ) {
 | 
			
		||||
    uint8_t function = 0;
 | 
			
		||||
 | 
			
		||||
    uint16_t vendorID = CheckVendor(bus, device);
 | 
			
		||||
    if (vendorID == 0xFFFF) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    checkFunction (bus, device, function );
 | 
			
		||||
    headerType = getHeaderType(bus, device, function );
 | 
			
		||||
    if( (headerType & 0x80) != 0) {
 | 
			
		||||
        /* It is  a multi-function device, so check remaining functions */
 | 
			
		||||
        for (function = 1; function < 8; function++){
 | 
			
		||||
            if (CheckVendor(bus, device)!= 0xFFFF){
 | 
			
		||||
                checkFunction(bus, device, function );
 | 
			
		||||
            } 
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void checkFunction (uint8_t bus, uint8_t device, uint8_t function ){
 | 
			
		||||
    uint8_t baseClass;
 | 
			
		||||
    uint8_t subClass;
 | 
			
		||||
    uint8_t secondaryBus;
 | 
			
		||||
 | 
			
		||||
    baseClass = getBaseClass(bus, device, function);
 | 
			
		||||
    subClass = getSubClass (bus, device, function );
 | 
			
		||||
    if ( (baseClass == 0x06) && (subClass == 0x04)){
 | 
			
		||||
        secondaryBus = getSecondaryBus(bus,device, function);
 | 
			
		||||
        checkBus(secondaryBus);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Brute-force scan
 | 
			
		||||
void checkAllBuses (){
 | 
			
		||||
    uint16_t bus;
 | 
			
		||||
    uint8_t device;
 | 
			
		||||
 | 
			
		||||
    for(bus = 0; bus < 256; bus++){
 | 
			
		||||
        for(device = 0; device < 32; device++){
 | 
			
		||||
            checkDevice(bus,device);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Recursive scan
 | 
			
		||||
void checkBus (uint8_t bus){
 | 
			
		||||
    uint8_t device;
 | 
			
		||||
 | 
			
		||||
    for(device = 0; device < 32; device ++){
 | 
			
		||||
        checkDevice(bus,device);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void checkAllBuses(){
 | 
			
		||||
    uint8_t function; 
 | 
			
		||||
    uint8_t bus;
 | 
			
		||||
 | 
			
		||||
    headerType = getHeaderType(0,0,0);
 | 
			
		||||
    if ( (headerType & 0x80) == 0 ){
 | 
			
		||||
        /* Single PCI host controller */
 | 
			
		||||
        checkBus(0);
 | 
			
		||||
    } else{
 | 
			
		||||
        /* Multiple PCI host controllers */
 | 
			
		||||
        for (function = 0; function < 8; function++){
 | 
			
		||||
            if( CheckVendor(0,0) != 0xFFFF) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            bus = function;
 | 
			
		||||
            checkBus(bus);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								src/kernel/pci.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/kernel/pci.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "io.h"
 | 
			
		||||
// Configuration Space Access Mechanism #1
 | 
			
		||||
#define CONFIG_ADDRESS 0xCF8 // Configuration adress that is to be accessed
 | 
			
		||||
#define CONFIG_DATA 0xCFC // Will do the actual configuration operation
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
CONFIG_ADDRESS 
 | 
			
		||||
 | 
			
		||||
32 bit register 
 | 
			
		||||
 | 
			
		||||
bit 31      Enable bit      (Should CONFIG_DATA be translatedc to configuration cycles)      
 | 
			
		||||
bit 30 - 24 Reserved    
 | 
			
		||||
bit 23 - 16 Bus Number      (Choose a specific PCI BUS)
 | 
			
		||||
bit 15 - 11 Device Number   (Selects specific device one the pci bus)
 | 
			
		||||
bit 10 - 8  Function Number (Selects a specific function in a device)
 | 
			
		||||
bit 7 -  0  Register Offset (Offset in the configuration space of 256 Bytes ) NOTE: lowest two bits will always be zero 
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
PCI Device structure
 | 
			
		||||
 | 
			
		||||
Register    offset  bits 31-24  bits 23-16  bits 15-8   bits 7-0
 | 
			
		||||
00          00      Device ID   <----       Vendor  ID  <-------
 | 
			
		||||
01          04      Status      <----       Command     <-------
 | 
			
		||||
02          08      Class code  Sub class   Prog IF     Revision ID
 | 
			
		||||
03          0C      BIST        Header Type Ltncy Timer Cache line Size
 | 
			
		||||
04          10      Base address #0 (BAR0) 
 | 
			
		||||
05          14      Base address #1 (BAR1) 
 | 
			
		||||
06          18      Base address #2 (BAR2) 
 | 
			
		||||
07          1C      Base address #3 (BAR3)
 | 
			
		||||
08          20      Base address #4 (BAR4)
 | 
			
		||||
09          24      Base address #5 (BAR5)
 | 
			
		||||
0A          28      Cardbus CIS Pointer
 | 
			
		||||
0B          2C      Subsystem ID <------   Subsystem Vendor ID  <-------
 | 
			
		||||
0C          30      Expansion ROM base address
 | 
			
		||||
0D          34      Reserved     <-------   Capabilities Pointer <------
 | 
			
		||||
0E          38      Reserved    <-------    <--------   <--------
 | 
			
		||||
0F          3C      Max ltncy   Min Grant   Interrupt PIN   Interrupt Line
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
The idea for now is to support the minimal things necessary to find ATA supported drives
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Lets write some boiler plate configuration code
 | 
			
		||||
 | 
			
		||||
uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
 | 
			
		||||
 | 
			
		||||
uint16_t CheckVendor (uint8_t bus, uint8_t slot);
 | 
			
		||||
 | 
			
		||||
void checkDevice (uint8_t bus, uint8_t device );
 | 
			
		||||
@ -49,6 +49,8 @@ void read_rtc() {
 | 
			
		||||
      year = get_RTC_register(0x09);
 | 
			
		||||
      if(century_register != 0) {
 | 
			
		||||
            century = get_RTC_register(century_register);
 | 
			
		||||
      } else {
 | 
			
		||||
            century = 21;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
      do {
 | 
			
		||||
@ -141,7 +143,7 @@ void WriteTOCMOS(unsigned char array[])
 | 
			
		||||
       asm("cli\n\t"       // Clear interrupts
 | 
			
		||||
         "mov al,index\n\t"    // move index address
 | 
			
		||||
         "out 0x70,al\n\t"     // copy address to CMOS register
 | 
			
		||||
         /* some kind of real delay here is probably best 
 | 
			
		||||
         // some kind of real delay here is probably best 
 | 
			
		||||
         "mov al,tvalue\n\t"   // move value to al
 | 
			
		||||
         "out 0x71,al\n\t"   // write 1 byte to CMOS
 | 
			
		||||
         "sti\n\\t"   );        // Enable interrupts
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/libc/include/string.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/libc/include/string.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
#include "string.h"
 | 
			
		||||
 | 
			
		||||
size_t strlen(const char* str) {
 | 
			
		||||
    size_t len = 0;
 | 
			
		||||
    while(str[len]){
 | 
			
		||||
        len++;
 | 
			
		||||
    }
 | 
			
		||||
    return len;
 | 
			
		||||
}
 | 
			
		||||
@ -1,8 +1,3 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
size_t strlen(const char* str){
 | 
			
		||||
    size_t len = 0;
 | 
			
		||||
    while(str[len]){
 | 
			
		||||
        len++;
 | 
			
		||||
    }
 | 
			
		||||
    return len;
 | 
			
		||||
}
 | 
			
		||||
size_t strlen(const char* str);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user