Moved some files around in preparation for completely changing the way that booting works

This commit is contained in:
2021-09-23 15:09:06 +01:00
parent 2c4c76d1e7
commit d617de6a0c
19 changed files with 4 additions and 69 deletions
+122
View File
@@ -0,0 +1,122 @@
#include "atapio.h"
// Disk code
// Primary ATA Bus: 0x1f0 to 0x1f7
// Device Control Register: 0x3f6
// Secondary ATA Bus: 0x170 to 0x177
// Device Control Register: 0x376
uint16_t identify_result[256];
uint32_t total_28_lbas = 0;
uint8_t* rootDirEntries = 0x1000000;
uint16_t* FAT1 = 0x1002000;
uint16_t countReserved;
uint8_t countFATs;
uint16_t countRDEs;
uint16_t sectorsPerFAT;
void init_atapio() {
countReserved = *(uint16_t*)0x7c0e;
countFATs = *(uint8_t*)0x7c10;
countRDEs = *(uint16_t*)0x7c11;
sectorsPerFAT = *(uint16_t*)0x7c16;
// Select Drive 0 on the Primary Bus
outb(0x1f6, 0xa0);
// Set sector count to 0 for IDENTIFY
outb(0x1f2, 0);
// Set LBAlo to 0
outb(0x1f3, 0);
// Set LBAmid to 0
outb(0x1f4, 0);
// Set LBAhi to 0
outb(0x1f5, 0);
// Send IDENTIFY command
outb(0x1f7, 0xec);
uint8_t status = inb(0x1f7);
if (status) {
while ((status = inb(0x1f7)) & 0x80);
if ( !(inb(0x1f4) || inb(0x1f5)) ) {
while ( !(status & 8 || status & 1) )
status = inb(0x1f7);
if (!(status & 1)) {
for (int index=0; index<256; index++)
identify_result[index] = inw(0x1f0);
}
}
}
total_28_lbas = *(uint32_t*)(identify_result+60);
// We've initialised now, let's load the FAT and RootDirEntries.
read_sectors(sectorsPerFAT * countFATs + 1, countRDEs / 16, rootDirEntries);
read_sectors(1, sectorsPerFAT, FAT1);
}
void read_sector(uint32_t address, uint8_t* buffer) {
outb(0x1f6, 0xe0 | ((address>>24)&0x0f));
// Read a single sector
outb(0x1f2, 1);
// Set LBAlo, LBAmid and LBAhi
outb(0x1f3, address);
outb(0x1f4, address>>8);
outb(0x1f5, address>>16);
// Send read command
outb(0x1f7, 0x20);
// Poll
uint8_t status = inb(0x1f7);
while ( (status & 0x80) && !(status & 8) )
status = inb(0x1f7);
for (int index=0; index<256; index++)
((uint16_t*)buffer)[index] = inw(0x1f0);
}
void read_sectors(uint32_t address, int count, uint8_t* buffer) {
for (int i=0; i<count; i++) {
read_sector(address+i, buffer+512*i);
for (int i=0; i<15; i++)
inb(0x1f7);
}
}
uint16_t file_exists(char* filename) {
for (int i=0; i<countRDEs; i++) {
bool found = strcmp(rootDirEntries+(i*32), filename, 11);
if (found) {
uint16_t* correctEntry = (rootDirEntries+(i*32));
return correctEntry[13];
}
}
return 0;
}
void load_file(char* filename, uint8_t* destination) {
uint16_t location = file_exists(filename);
if (!location)
return;
int offset = 0;
bool loaded = false;
while (!loaded) {
uint16_t fromSector = location + (sectorsPerFAT * countFATs) + (countRDEs / 16) - 1;
read_sector(fromSector, destination+offset);
offset += 512;
location = FAT1[location++];
if (location == 0xffff)
loaded = true;
}
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef ATA_PIO
#define ATA_PIO
#include <stdbool.h>
#include "io.h"
#include "types.h"
#include "strings.h"
#include "screenstuff.h"
void init_atapio();
void read_sector(uint32_t address, uint8_t* buffer);
void read_sectors(uint32_t address, int count, uint8_t* buffer);
uint16_t file_exists(char* filename);
void load_file(char* filename, uint8_t* location);
#endif
+48
View File
@@ -0,0 +1,48 @@
#include "idt.h"
GateEntry idt[256];
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type) {
uint32_t handler_addr = (uint16_t)handler;
uint16_t* handler_halves = (uint16_t*)&handler_addr;
idt[interrupt_number] = (GateEntry){
.offset_low = handler_halves[0],
.selector = code_segment,
.zero = 0,
.type = type,
.offset_high = handler_halves[1]
};
}
__attribute__((interrupt)) void interrupt_20(struct interrupt_frame* frame) {
// printf("Interrupt 20 received!!\n");
outb(0x20, 0x20);
}
__attribute__((interrupt)) void ignore_interrupt(struct interrupt_frame* frame) {
// Do nothing
}
void init_idt() {
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
asm volatile("lidt %0" : : "m" (desc));
for (int i=0; i<256; i++)
set_entry(i, 0x08, &ignore_interrupt, 0x8E);
set_entry(0x20, 0x08, &interrupt_20, 0x8E);
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, 0x20);
outb(0xA1, 0x28);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, 0x00);
outb(0xA1, 0x00);
}
void enable_idt() {
asm ("sti");
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef IDT_H
#define IDT_H
#include "types.h"
#include "screenstuff.h"
struct interrupt_frame{
uint16_t ip;
uint16_t cs;
uint16_t flags;
uint16_t sp;
uint16_t ss;
};
extern void load_idt();
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type);
void init_idt();
void enable_idt();
typedef struct {
uint16_t offset_low;
uint16_t selector;
uint8_t zero;
uint8_t type;
uint16_t offset_high;
}__attribute__((packed)) GateEntry;
typedef struct {
uint16_t size;
uint32_t offset;
}__attribute__((packed)) idt_desc;
#endif
+19
View File
@@ -0,0 +1,19 @@
#include "io.h"
void outb(uint16_t portnumber, uint8_t data) {
asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber));
}
uint8_t inb(uint16_t portnumber) {
uint8_t result;
asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber));
return result;
}
void outw(uint16_t portnumber, uint16_t data) {
asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber));
}
uint16_t inw(uint16_t portnumber) {
uint16_t result;
asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber));
return result;
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef IO_H
#define IO_H
#include "types.h"
void outb(uint16_t portnumber, uint8_t data);
uint8_t inb(uint16_t portnumber);
void outw(uint16_t portnumber, uint16_t data);
uint16_t inw(uint16_t portnumber);
#endif
+83
View File
@@ -0,0 +1,83 @@
#include "types.h"
#include "screenstuff.h"
#include "io.h"
#include "idt.h"
#include "keyboard.h"
#include "strings.h"
#include "atapio.h"
int main() {
init_idt();
init_term();
printf("KERNEL32 OK!\n");
printf("Hello, World!\n\nWe are running XnoeOS Code in C now, Protected Mode has been achieved and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n");
init_keyboard();
enable_idt();
init_atapio();
uint8_t sector[512];
read_sector(0, sector);
printf("OEM ID: %s\n", (char*)(sector+0x3));
char hellotxt[1024];
load_file("HELLO TXT", hellotxt);
printf("%s", hellotxt);
while (1) {
printf(">>> ");
char buffer[128];
for (int i=0; i<128; i++)
buffer[i] = 0;
readline(128, buffer);
char* rest = split_on_first(' ', buffer);
if (strcmp(buffer, "help", 4)) {
printf(
"XnoeOS 32 Bit Mode Help.\n"
"------------------------\n"
" - help\n"
" : Shows this message\n"
" - clear\n"
" : Clears the screen\n"
" - echo\n"
" : Repeats the text written afterwards\n"
);
} else if (strcmp(buffer, "clear", 5)) {
clear_screen();
set_curpos(0, 0);
} else if (strcmp(buffer, "echo", 4)) {
printf("%s\n", rest);
} else if (strcmp(buffer, "type", 4)) {
char filenamebuffer[12];
uint8_t* filebuffer = 0x1006400;
decode_filename(rest, filenamebuffer);
if (!file_exists(filenamebuffer)) {
printf("File %s not found!\n", filenamebuffer);
continue;
}
for (int i=0; i<1024; i++)
hellotxt[i] = 0;
load_file(filenamebuffer, filebuffer);
printf(filebuffer);
} else {
char filenamebuffer[12];
decode_filename(buffer, filenamebuffer);
if (!file_exists(filenamebuffer)) {
printf("Bad Command or filename!\n");
continue;
}
}
}
}
+11
View File
@@ -0,0 +1,11 @@
[BITS 32]
_start:
mov ax, 10h
mov ds, ax
mov ss, ax
mov esp, 90000h
call main
extern main
+95
View File
@@ -0,0 +1,95 @@
#include "keyboard.h"
char key_to_char[128] = {
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\',
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
char key_to_char_caps[128] = {
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0,
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\',
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
char key_to_char_shift[128] = {
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0,
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|',
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+',
'1', '2', '3', '0', '.', 0, 0, 0, 0, 0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
uint8_t current_scancode = 0;
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame) {
current_scancode = inb(0x60);
outb(0x20, 0x21);
}
void init_keyboard() {
set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E);
while (inb(0x64) & 1) {
inb(0x60);
}
outb(0x64, 0xAE);
outb(0x64, 0x20);
uint8_t keyboard_status = (inb(0x60) | 1) & ~0x10;
outb(0x64, 0x60);
outb(0x60, keyboard_status);
outb(0x60, 0xF4);
}
bool caps_on = false;
bool shift_on = false;
void readline(int max, char* buffer) {
int index = 0;
uint8_t scancode = 0;
while (scancode != 0x1c && index < max) {
scancode = current_scancode;
char decoded = 0;
if ((scancode&0x7f) == 0x2a)
shift_on = !(scancode&0x80);
if (scancode == 0x3a)
caps_on ^= 1;
if (scancode == 0x0e && index > 0) {
set_curpos_raw(get_curpos()-1);
non_moving_put(' ');
buffer[--index] = 0;
}
if (shift_on)
decoded = key_to_char_shift[scancode&0x7f];
else if (caps_on)
decoded = key_to_char_caps[scancode&0x7f];
else
decoded = key_to_char[scancode&0x7f];
if (decoded && scancode < 0x80) {
buffer[index++] = decoded;
printf("%c", decoded);
}
while (scancode == current_scancode);
}
printf("\n");
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H
#include <stdbool.h>
#include "io.h"
#include "screenstuff.h"
#include "idt.h"
void init_keyboard();
void readline(int max, char* buffer);
#endif
+160
View File
@@ -0,0 +1,160 @@
#include "screenstuff.h"
uint16_t* VMEM_ADDR = (uint16_t*)0xb8000;
const int TERM_WIDTH = 80;
const int TERM_HEIGHT = 25;
int cursor_x = 0;
int cursor_y = 0;
uint16_t get_curpos() {
uint16_t cursor_position = 0;
uint8_t* cursor_position_split = (uint8_t*)&cursor_position;
outb(0x3D4, 0x0F);
cursor_position_split[0] = inb(0x3D5);
outb(0x3D4, 0x0E);
cursor_position_split[1] = inb(0x3D5);
return cursor_position;
}
void init_term() {
uint16_t cursor_position = get_curpos();
cursor_y = cursor_position / TERM_WIDTH;
cursor_x = cursor_position % TERM_WIDTH;
}
void clear_screen() {
for (int i=0; i<TERM_WIDTH*TERM_HEIGHT; i++) {
VMEM_ADDR[i] = 0x0720;
}
}
void clear_line(int line) {
for (int x=0; x<TERM_WIDTH; x++) {
VMEM_ADDR[TERM_WIDTH*line + x] = 0x0720;
}
}
void set_curpos_raw(int curpos) {
uint8_t* cursor_position_split = (uint8_t*)&curpos;
outb(0x3D4, 0x0F);
outb(0x3D5, cursor_position_split[0]);
outb(0x3D4, 0x0E);
outb(0x3D5, cursor_position_split[1]);
cursor_x = (*(uint16_t*)cursor_position_split) % TERM_WIDTH;
cursor_y = (*(uint16_t*)cursor_position_split) / TERM_WIDTH;
}
void set_curpos(int x, int y) {
set_curpos_raw(y * TERM_WIDTH + x);
cursor_x = x;
cursor_y = y;
}
int int_to_decimal(unsigned int number, char* string_buffer) {
for (int i=0; i<11; i++)
string_buffer[i] = 0;
int index = 9;
unsigned int acc = number;
if (acc == 0)
string_buffer[index--] = '0';
while (acc != 0) {
string_buffer[index--] = 0x30+(acc%10);
acc /= 10;
}
return (index+1);
}
char dec_to_hex[16] = "0123456789abcdef";
int int_to_hex(unsigned int number, char* string_buffer) {
for (int i=0; i<9; i++)
string_buffer[i] = 0;
int index = 7;
unsigned int acc = number;
if (acc == 0)
string_buffer[index--] = '0';
while (acc != 0) {
string_buffer[index--] = dec_to_hex[acc%0x10];
acc /= 0x10;
}
return (index+1);
}
void printf(const char* string, ...) {
va_list ptr;
va_start(ptr, string);
int index = 0;
int count = 0;
char current;
while (current=string[index++]) {
count++;
if (current == '\n') {
cursor_x = 0;
cursor_y++;
}
if (cursor_x == TERM_WIDTH) {
cursor_x = 0;
cursor_y++;
}
if (cursor_y == TERM_HEIGHT) {
for (int i=1; i<TERM_HEIGHT; i++) {
for (int x=0; x<TERM_WIDTH; x++) {
int from = i * TERM_WIDTH + x;
int to = (i-1) * TERM_WIDTH + x;
VMEM_ADDR[to] = VMEM_ADDR[from];
}
}
clear_line(24);
cursor_y--;
}
if (current == '%') {
int type = string[index++];
int offset;
switch (type) {
case 'd':
char decimal_buffer[11];
offset = int_to_decimal(va_arg(ptr, int), decimal_buffer);
printf(decimal_buffer + offset);
break;
case 'x':
char hex_buffer[8];
offset = int_to_hex(va_arg(ptr, int), hex_buffer);
printf(hex_buffer + offset);
break;
case 's':
printf(va_arg(ptr, const char*));
break;
case 'c':
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
int promoted = va_arg(ptr, int);
char charred = promoted;
VMEM_ADDR[mem_pos] = charred + (0x07<<8);
break;
}
continue;
}
if (current != '\n') {
int mem_pos = cursor_y * TERM_WIDTH + cursor_x++;
VMEM_ADDR[mem_pos] = current + (0x07<<8);
}
}
set_curpos(cursor_x, cursor_y);
va_end(ptr);
}
void non_moving_put(char chr) {
int mem_pos = cursor_y * TERM_WIDTH + cursor_x;
VMEM_ADDR[mem_pos] = chr + (0x07<<8);
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef SCREENSTUFF_H
#define SCREENSTUFF_H
#include <stdarg.h>
#include "types.h"
#include "io.h"
uint16_t get_curpos();
void init_term();
void clear_screen();
void clear_line(int line);
void set_curpos_raw(int curpos);
void set_curpos(int x, int y);
int int_to_decimal(unsigned int number, char* string_buffer);
int int_to_hex(unsigned int number, char* string_buffer);
void printf(const char* string, ...);
void non_moving_put(char chr);
#endif
+69
View File
@@ -0,0 +1,69 @@
#include "strings.h"
bool strcmp(char* a, char* b, int max) {
int index = 0;
while (index < max) {
if (a[index] != b[index])
return false;
index++;
}
return true;
}
char* split_on_first(char delimeter, char* string) {
int index = 0;
char current;
while (current = string[index++]) {
if (current == delimeter) {
string[index-1] = 0;
return string+index;
}
}
return 0;
}
int string_split(char delimeter, char* string, char** pointer_array) {
int index = 0;
int last_split_index = 0;
int split_count = 0;
char current;
while (current = string[index]) {
if (current == delimeter) {
string[index] = 0;
pointer_array[split_count++] = (string+last_split_index);
last_split_index = (index+1);
}
index++;
}
// Add remaining part of the string to the pointer_array
pointer_array[split_count] = (string+last_split_index);
return split_count;
}
void decode_filename(char* nice_name, char* filenamebuffer) {
// Clear filenamebuffer
for (int i=0; i<11; i++)
filenamebuffer[i] = ' ';
filenamebuffer[11] = 0;
int fbIndex = 0;
for (int i=0; i<12; i++) {
if (nice_name[i] == 0)
return;
if (nice_name[i] == '.') {
fbIndex = 8;
continue;
}
if (nice_name[i] >= 0x65 && nice_name[i] <= 0x65+26)
filenamebuffer[fbIndex++] = nice_name[i] & (0xff - 32);
else
filenamebuffer[fbIndex++] = nice_name[i];
}
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef STRINGS_H
#define STRINGS_H
#include <stdbool.h>
bool strcmp(char* a, char* b, int max);
char* split_on_first(char delimeter, char* string);
int string_split(char delimeter, char* string, char** pointer_array);
void decode_filename(char* nice_name, char* filenamebuffer);
#endif
+11
View File
@@ -0,0 +1,11 @@
#ifndef TYPES_H
#define TYPES_H
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef long int int32_t;
typedef unsigned long int uint32_t;
#endif