Remove old boot_stage2 directory

This commit is contained in:
Xnoe 2022-04-06 20:59:33 +01:00
parent a0d0454e32
commit edd6e82c2c
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
13 changed files with 0 additions and 740 deletions

View File

@ -1,122 +0,0 @@
#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 + countReserved, countRDEs / 16, rootDirEntries);
read_sectors(countReserved, 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) + (countReserved - 1) - 1;
read_sector(fromSector, destination+offset);
offset += 512;
location = FAT1[location++];
if (location == 0xffff)
loaded = true;
}
}

View File

@ -1,16 +0,0 @@
#ifndef ATA_PIO
#define ATA_PIO
#include <stdbool.h>
#include "io.h"
#include "types.h"
#include "strings.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

View File

@ -1,14 +0,0 @@
OUTPUT_FORMAT(binary)
OUTPUT_ARCH(i386:i386)
OUTPUT(build/boot_stage2/boot.bin)
SECTIONS {
. = 0x7E00;
.text : {
build/c_code_entry.o(.text)
build/boot_stage2/main.o(.text)
build/boot_stage2/*(.text)
}
}

View File

@ -1,19 +0,0 @@
#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;
}

View File

@ -1,12 +0,0 @@
#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

View File

@ -1,199 +0,0 @@
#include "atapio.h"
#include "screenstuff.h"
#include "paging.h"
typedef struct {
uint32_t base_low;
uint32_t base_high;
uint32_t length_low;
uint32_t length_high;
uint32_t type;
uint32_t acpi3_extended;
}__attribute__((packed)) e820entry;
uint8_t* bitmap = 0x100000;
void set_bit(uint32_t offset, uint8_t* buffer) {
uint32_t index = offset / 8;
uint32_t bit = offset % 8;
buffer[index] |= (1<<(7 - bit));
}
void unset_bit(uint32_t offset, uint8_t* buffer) {
uint32_t index = offset / 8;
uint32_t bit = offset % 8;
buffer[index] &= (255 - (1<<(7 - bit)));
}
void memset(uint8_t* base, uint32_t count, uint8_t to) {
for (int i=0; i<count; i++) {
base[i] = to;
}
}
void mark_unavailble(uint32_t address, uint32_t size, uint8_t* buffer) {
// This function takes an address and length and marks the corresponding pages as unavailable.
address -= address % 4096;
if (size % 4096)
size += 4096 - (size % 4096);
address /= 4096;
size /= 4096;
for (int i=0; i<size; i++) {
unset_bit(address + i, buffer);
}
}
char* stringify_type(uint32_t type) {
switch (type) {
case 1:
return "Usable";
case 3:
return "ACPI Reclaimable";
case 4:
return "ACPI NVS";
case 5:
return "Bad memory";
default:
return "Reserved";
}
}
void main() {
init_term();
init_atapio();
// e820 memory map exists at 0x20000
e820entry* e820_entries = 0x20000;
// Zero out the bitmap.
memset(bitmap, 0x20000, 0);
// Ensure the bitmap data is clear
for (int i=0; i<0x20000; i++)
if (bitmap[i])
printf("Found data in bitmap at %x!\n", (bitmap+i));
for (int i=0; e820_entries[i].length_low != 0 || e820_entries[i].length_high != 0; i++) {
e820entry entry = e820_entries[i];
printf("BIOS-e820: Starting %x%x, length %x%x is %s\n", entry.base_high, entry.base_low, entry.length_high, entry.length_low, stringify_type(entry.type));
if (entry.type != 1)
continue;
uint32_t base = entry.base_low;
uint32_t length = entry.length_low;
if (base % 4096) {
// Memory isn't page aligned, we need to fix that.
uint32_t add_offset = 4096 - (base % 4096);
if (length > add_offset) {
base += add_offset;
length -= add_offset;
}
}
uint32_t page_index = base / 4096;
printf("Page Index: %d\nLength (Pages): %d\n", page_index, length / 4096);
for (int j=0; length > 4096; length -= 4096, j++) {
set_bit(page_index + j, bitmap);
}
}
mark_unavailble(bitmap, 0x20000, bitmap);
// Page Directory
PDE* kernel_page_directory = bitmap + 0x20000;
// Clear the PD
memset((uint8_t*)kernel_page_directory, 4096, 0);
// Clear 4MB of RAM from 0x121000 to 0x521000 for the 1024 page tables
memset((uint8_t*)0x121000, 0x400000, 0);
// Construct a 1024 long PTE** at 0x521000
for (int i=0; i<1024; i++) {
((uint32_t*)0x521000)[i] = 0x121000 + 0x1000*i;
}
PTE** kernel_page_tables = 0x521000;
for (int i = 0; i < 1023; i++) {
kernel_page_directory[i] = (PDE){
.address = (uint32_t)(kernel_page_tables[i]) >> 12,
.available = 0,
.page_4mb = 0,
.accessed = 0,
.disable_cache = 0,
.write_through_cache = 0,
.privilege = 0,
.present = 1,
.read_write = 1,
.ignored = 0,
.ignored2 = 0
};
}
// Mark unavailable bitmap to 0x522000
mark_unavailble(bitmap, 0x4000000, bitmap);
// Now we want to map some stuff.
// But first, we should load the kernel somewhere
uint8_t* kernel_location = 0x542000; // Just load it at 0x524000 for now
mark_unavailble(kernel_location, 0x10000, bitmap); // Just treat the kernel as not growing beyond 32k for now.
map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 0x10); // Map 16 pages from 0x522000 to 0xc0000000;
map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000
map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000
map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000
map_4k_phys_to_virt(0x521000, 0xc0502000, kernel_page_directory, kernel_page_tables); // Map the PTE** data, we'll need to convert the pointers to point at kernel space at some point.
map_many_4k_phys_to_virt(0xa0000, 0xc07a0000, kernel_page_directory, kernel_page_tables, 0x20); // Map 32 pages from 0xa0000 to 0xa0000
mark_unavailble(0xa0000, 0x20000, bitmap);
uint8_t* vm_bitmap = 0x522000;
mark_unavailble(vm_bitmap, 0x20000, bitmap);
memset(vm_bitmap, 0x20000, 0xff);
mark_unavailble(0xc07a0000, 0x20000, vm_bitmap);
mark_unavailble(0xc0000000, 0x10000, vm_bitmap);
mark_unavailble(0xc0100000, 0x1000, vm_bitmap);
mark_unavailble(0xc0101000, 0x400000, vm_bitmap);
mark_unavailble(0xc0501000, 0x1000, vm_bitmap);
mark_unavailble(0xc0502000, 0x1000, vm_bitmap);
mark_unavailble(0xc0600000, 0x20000, vm_bitmap);
mark_unavailble(0xc0620000, 0x20000, vm_bitmap);
mark_unavailble(0xc1000000, 0x6000, vm_bitmap);
// Map the bitmap
map_many_4k_phys_to_virt(0x100000, 0xc0600000, kernel_page_directory, kernel_page_tables, 32);
// Map the virtual memory bitmap
map_many_4k_phys_to_virt(0x522000, 0xc0620000, kernel_page_directory, kernel_page_tables, 32);
map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables);
// Map the stack
map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 16);
map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 16);
mark_unavailble(0x8a000, 0x10000, bitmap);
load_file("KERNEL BIN", kernel_location);
printf("Stage2 success!\n");
//while (1);
asm volatile("mov %0, %%eax;"
"mov %%eax, %%cr3;"
"mov %%cr0, %%eax;"
"or $0x80000000, %%eax;"
"mov %%eax, %%cr0" : : "m" (kernel_page_directory));
((void(*)(void))0xc0000000)();
}

View File

@ -1,46 +0,0 @@
#include "paging.h"
typedef struct {
uint32_t page_offset : 12;
uint32_t pt_index : 10;
uint32_t pd_index : 10;
}__attribute__((packed)) split_addr;
void map_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables) {
split_addr* split = (split_addr*)&virtual;
page_directory[split->pd_index] = (PDE){
.address = (uint32_t)(page_tables[split->pd_index]) >> 12,
.available = 0,
.page_4mb = 0,
.accessed = 0,
.disable_cache = 0,
.write_through_cache = 0,
.privilege = 0,
.present = 1,
.read_write = 1,
.ignored = 0,
.ignored2 = 0
};
page_tables[split->pd_index][split->pt_index] = (PTE){
.address = physical >> 12,
.available = 0,
.global = 0,
.accessed = 0,
.disable_cache = 0,
.dirty = 0,
.write_through_cache = 0,
.privilege = 0,
.present = 1,
.read_write = 1,
.ignored = 0
};
}
void map_many_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables, uint32_t count) {
for (int i=0; i<count; i++)
map_4k_phys_to_virt(physical + 4096*i, virtual + 4096*i, page_directory, page_tables);
}

View File

@ -1,37 +0,0 @@
#ifndef PAGING_H
#define PAGING_H
#include <stdbool.h>
#include "types.h"
typedef struct {
uint32_t present : 1;
uint32_t read_write : 1;
uint32_t privilege : 1;
uint32_t write_through_cache : 1;
uint32_t disable_cache : 1;
uint32_t accessed : 1;
uint32_t ignored2 : 1;
uint32_t page_4mb : 1;
uint32_t ignored : 1;
uint32_t available : 3;
uint32_t address : 20;
}__attribute__((packed)) PDE;
typedef struct {
uint32_t present : 1;
uint32_t read_write : 1;
uint32_t privilege : 1;
uint32_t write_through_cache : 1;
uint32_t disable_cache : 1;
uint32_t accessed : 1;
uint32_t dirty : 1;
uint32_t ignored : 1;
uint32_t global : 1;
uint32_t available : 3;
uint32_t address : 20;
}__attribute__((packed)) PTE;
void map_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables);
void map_many_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_directory, PTE** page_tables, uint32_t count);
#endif

View File

@ -1,165 +0,0 @@
#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<8; i++)
string_buffer[i] = '0';
string_buffer[8] = 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);
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);
}

View File

@ -1,19 +0,0 @@
#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

View File

@ -1,69 +0,0 @@
#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] >= 0x61 && nice_name[i] <= 0x7f)
filenamebuffer[fbIndex++] = nice_name[i] - 32;
else
filenamebuffer[fbIndex++] = nice_name[i];
}
}

View File

@ -1,11 +0,0 @@
#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

View File

@ -1,11 +0,0 @@
#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