Moved reading file from disk to its own super visor terminal command

- Updated gdt assembly
- Updated Interrupt service request handlers
- Improved virtual memory manager
- NOTE: we're dependent on identity mappings for the heap to work
This commit is contained in:
Nigel Barink 2023-02-08 14:07:44 +01:00
parent 7993a2d172
commit 520104a43a
23 changed files with 474 additions and 701 deletions

View File

@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
CFLAGS = -ffreestanding -Og -ggdb -Wall -Wextra
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o $(BUILD_DIR)/KHeap.o $(BUILD_DIR)/pci.o $(BUILD_DIR)/pcidevice.o $(BUILD_DIR)/atapiDevice.o $(BUILD_DIR)/ataDevice.o $(BUILD_DIR)/rsdp.o
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o $(BUILD_DIR)/KHeap.o $(BUILD_DIR)/pci.o $(BUILD_DIR)/pcidevice.o $(BUILD_DIR)/atapiDevice.o $(BUILD_DIR)/ataDevice.o $(BUILD_DIR)/rsdp.o $(BUILD_DIR)/acpi.o
SRC_DIR = source
BUILD_DIR = build
@ -36,12 +36,12 @@ run: all
virtualboxvm --startvm "BarinkOS_test"
debug: all
objcopy --only-keep-debug build/myos.bin kernel.sym
$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int
$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int -no-shutdown -no-reboot
test:
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo -d int -no-shutdown -no-reboot
test_iso:
$(EMULATOR) -boot d -cdrom $(BUILD_DIR)/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo
$(EMULATOR) -boot d -cdrom $(BUILD_DIR)/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -d int -no-reboot -no-shutdown
test_disk:
$(EMULATOR) -boot d -drive format=raw,file=build/disk.img -serial stdio -vga std -display gtk -m 2G -cpu core2duo
@ -97,6 +97,9 @@ $(BUILD_DIR)/ataDevice.o:
$(BUILD_DIR)/rsdp.o:
$(CPP) -c $(SRC_DIR)/kernel/drivers/acpi/rsdp.cpp -o $(BUILD_DIR)/rsdp.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/acpi.o:
$(CPP) -c $(SRC_DIR)/kernel/drivers/acpi/acpi.cpp -o $(BUILD_DIR)/acpi.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/pit.o:
$(CPP) -c $(SRC_DIR)/kernel/drivers/pit/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
@ -126,6 +129,7 @@ $(BUILD_DIR)/cpu.o:
$(CPP) -c $(SRC_DIR)/kernel/cpu.cpp -o $(BUILD_DIR)/cpu.o $(CFLAGS) -fno-exceptions -fno-rtti
# Assembly -> Object files
$(BUILD_DIR)/boot.o:
$(AS) $(SRC_DIR)/kernel/boot/boot.s -o $(BUILD_DIR)/boot.o

View File

@ -29,7 +29,6 @@
<input type="checkbox" /> USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \
<input type="checkbox" /> ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \
<input type="checkbox" /> ATAPI support \
<input type="checkbox" /> Keyboard support ( P/S2 Keyboard) \
<input type="checkbox" checked/> Memory Management (MMU)
<input type="checkbox" /> Hardware Management system
@ -49,3 +48,4 @@
<input type="checkbox" /> Basic Window server/client \
<input type="checkbox" /> EXT2 Filesystem
<input type="checkbox" /> USTAR Filesystem \
<input type="checkbox" /> FAT16 Filesystem \

View File

@ -83,7 +83,7 @@ isPaging:
call prekernelSetup
# Unmap the identity mapping as it is now unnecessary
movl $0, boot_page_directory + 0
# movl $0, boot_page_directory + 0
# Reload cr3 to force tlb flush
movl %cr3, %ecx

View File

@ -0,0 +1,14 @@
#include "acpi.h"
RSDPTR* ACPI::rsd_ptr;
RSDT* ACPI::rsd_table;
void ACPI::initialize(){
// Find the Root System Description Pointer
ACPI::rsd_ptr = FindRSD();
printRSD(rsd_ptr);
// Get the Root System Description Table
ACPI::rsd_table = getRSDT(rsd_ptr);
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "rsdp.h"
class ACPI {
public:
static void initialize();
// In the future ACPI might start
// doing more systems initialization
private:
static RSDPTR* rsd_ptr;
static RSDT* rsd_table;
};

View File

@ -27,8 +27,6 @@ struct RSDT{
uint32_t PointerToSDT[]; // Length of array : (header.Length - sizeof(header))/ 4
}__attribute__((packed));
//NOTE: only scans EBDA enough to find RSD PTR in QEMU
RSDPTR* FindRSD();
void printRSD(RSDPTR* rsd);

View File

@ -155,7 +155,7 @@ inline void init_IDE( uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3,
// 3- Detect ATA-ATAPI Devices:
void DetectDevices(){
inline void DetectDevices(){
int i, j, k, count = 0;
for (i = 0; i < 2; i++)
@ -228,7 +228,7 @@ void DetectDevices(){
}
void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4){
inline void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4){
// 1 Detect I/O Ports which interface an IDE Controller
// Based on the implementation within serenity

View File

@ -185,7 +185,11 @@ void PrintPCIDeviceInfo (PCIBusAddress& PCIDeviceAddress)
}
void PCI_Enumerate(){
int devicesFound = 0;
int devicesFound = 0;
printf("Start finding devices, Found: %d devices");
// loop through all possible busses, devices and their functions;
for( int bus = 0 ; bus < 256 ; bus++)
{

View File

@ -10,8 +10,6 @@
extern const char* ClassCodeTable [0x13];
// Note: this could be used to make the api for receiving PCI class codes a bit
// nicer.
struct ClassCodes {

View File

@ -1,19 +0,0 @@
.global LoadGlobalDescriptorTable
LoadGlobalDescriptorTable:
lgdt gdtDescriptor
movw $16, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
jmp $8,$flush
flush:
ret

View File

@ -1,58 +0,0 @@
#include "gdtc.h"
#include "../terminal/kterm.h"
#define NULL_SEGMENT 0
#define KERNEL_CODE_SEGMENT 1
#define KERNEL_DATA_SEGMENT 2
#define USER_CODE_SEGMENT 3
#define USER_DATA_SEGMENT 4
SegmentDescriptor GlobalDescriptorTable[5];
GlobalDescriptorTableDescriptor gdtDescriptor;
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){
GlobalDescriptorTable[which].base_low = (base & 0xFFFF );
GlobalDescriptorTable[which].base_middle = (base >> 6) & 0xFF;
GlobalDescriptorTable[which].base_high = (base >> 24) & 0xFF;
GlobalDescriptorTable[which].limit_low = (limit & 0xFFFF);
GlobalDescriptorTable[which].granularity = ((limit >> 16) & 0x0F);
GlobalDescriptorTable[which].granularity |= (granularity & 0xF0);
GlobalDescriptorTable[which].access = access;
}
void initGDT(){
#ifdef __VERBOSE__
printf("Init GDT!\n");
#endif
// NULL segment
add_descriptor(NULL_SEGMENT, 0,0,0,0);
// Kernel Code Segment
add_descriptor(KERNEL_CODE_SEGMENT, 0, 0xFFFFFFFF, 0x9A, 0xCF);
// Kernel Data Segment
add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF);
// User Code Segment
// TODO:
// User Data Segement
// TODO:
// init Gdt Descriptor
gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
LoadGlobalDescriptorTable();
}

View File

@ -1,27 +0,0 @@
#include <stdint.h>
struct SegmentDescriptor {
unsigned short limit_low;
unsigned short base_low;
unsigned char base_middle;
unsigned char access;
unsigned char granularity;
unsigned char base_high;
}__attribute__((packed));
struct GlobalDescriptorTableDescriptor{
unsigned short limit;
unsigned int base;
}__attribute__((packed));
extern SegmentDescriptor GlobalDescriptorTable[];
extern GlobalDescriptorTableDescriptor gdtDescriptor;
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity );
extern "C" void LoadGlobalDescriptorTable();
void initGDT();

View File

@ -2,8 +2,7 @@
#include "../../drivers/pit/pit.h"
#include "../../drivers/ps-2/keyboard.h"
#include "../../cpu.h"
#include "../../drivers/ps-2/keyboard.h"
#include "../../memory/VirtualMemoryManager.h"
IDT_entry idt_table[256];
IDT_ptr idt_ptr;
@ -17,25 +16,25 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){
};
void irs_handler (registers regs) {
void irs_handler (registers* regs) {
uint32_t FaultingAddress;
//printf("(IRS) Interrupt number: %d \r", regs.int_no);
switch (regs.int_no)
switch (regs->int_no)
{
case 0:
// Divide Error #DE
printf("#DE\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 1:
// Debug Exception #DB
printf("#DB\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 2:
@ -46,49 +45,50 @@ void irs_handler (registers regs) {
case 3:
// Breakpoint Exception #BP
printf("#BP\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 4:
// Overflow Exception #OF
printf("#OF\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 5:
// BOUND Range Exceeded Exception #BR
printf("#BR\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 6:
// Invalid OpCode Exception #UD
printf("#UD\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 7:
// Device Not Available Exception #NM
printf("#NM\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 8:
// Double Fault Exception #DF
printf("#DF\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
while(true);
break;
case 9:
@ -99,64 +99,74 @@ void irs_handler (registers regs) {
case 10:
// Invalid TSS Exception #TS
printf("#TS\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
__asm__("cli;" "1: hlt;" "jmp 1b;");
break;
case 11:
// Segment Not Present #NP
printf("#NP\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 12:
// Stack Fault Exception #SS
printf("#SS\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 13:
case 13:{
// General Protection Exception #GP
printf("#GP\n");
printf("Accessing memory caused a general protectuion exception.\n");
printf("Fault due to entry at index: %d", (regs.err_code >> 3 & 0xFFF ) );
printf("Accessing memory caused a general protection exception.\n");
printf("Faulting instruction at addres: 0x%x\n", regs->eip );
printf("Error code: 0x%x\n", regs->err_code);
if(regs.err_code & 0x3 >> 1 == 0 ){
printf("* Index references GDT");
}
if(regs.err_code & 0x3 >> 1 == 1 ){
printf("* Index references IDT");
}
if (regs->err_code != 0){
printf("Fault due to entry at index: 0x%x (%d)\n", (regs->err_code >> 3 & 0xFFF ) , regs->err_code);
if(regs.err_code & 0x3 >> 1 == 2 ){
printf("* Index references LDT");
}
if(regs.err_code & 0x3 >> 1 == 4 ){
printf("* Index references IDT");
}
uint8_t table = regs->err_code >> 1 & 0x3 ;
if(table == 0 ){
printf("* Index references GDT\n");
}
if(table == 1 ){
printf("* Index references IDT\n");
}
if( regs.err_code & 0x1)
{
printf("* Originated externally!");
if(table == 2 ){
printf("* Index references LDT\n");
}
if(table == 3 ){
printf("* Index references IDT\n");
}
if( regs->err_code & 0x1)
{
printf("* Originated externally!\n");
}
}
__asm__("cli;" "1: hlt;" "jmp 1b;");
}
break;
case 14:
// Page Fault Exception #PF
printf("#PF\n");
#define ALIGN(addr, align) (((addr) & ~((align) - 1)) + (align))
FaultingAddress = GetCR2();
printf("Accessing the linear address 0x%x resulted in a page fault!\n\n", FaultingAddress);
// Error code of 32 bits are on the stack
@ -174,89 +184,86 @@ void irs_handler (registers regs) {
printf("REASON: \n\n");
if (regs.err_code & PF_ERR_PRESENT_BIT ){
if (regs->err_code & PF_ERR_PRESENT_BIT ){
printf("* Page protection violation!\n");
} else{
printf("* Page not-present!\n");
Immediate_Map(FaultingAddress, FaultingAddress - 0xC0000000);
}
if(regs.err_code & PF_ERR_WRITE_BIT){
if(regs->err_code & PF_ERR_WRITE_BIT){
printf("* Write access violation!\n");
} else{
printf("* Read access violation!\n");
}
if(regs.err_code & PF_ERR_USER_BIT){
if(regs->err_code & PF_ERR_USER_BIT){
printf("* Violation from user-space (CPL=3)\n");
}
if(regs.err_code & PF_ERR_INSTRUCTION_FETCH_BIT){
if(regs->err_code & PF_ERR_INSTRUCTION_FETCH_BIT){
printf("* Caused by an instruction fetch. \n");
}
/*
Check the error code to figure out what happened here
*/
__asm__("cli;" "1: hlt;" "jmp 1b;");
break;
case 16:
// x87 FPU Floating-point Error #MF
printf("#MF\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 17:
// Alignment Check Exception #AC
printf("#AC\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 18:
// Machine-Check Exception #MC
printf("#MC\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 19:
// SIMD Floating-point Exception #XM
printf("#XM\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 20:
// Virtualization Exception #VE
printf("#VE\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
case 21:
// Control Protection Exception #CP
printf("#CP\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax);
printf("EBP: 0x%x\n", regs.ebp);
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
break;
default:
// PANIC!!!
break;
}
}

View File

@ -36,7 +36,7 @@ extern "C" {
void irq_handler (registers regs);
void irs_handler (registers regs);
void irs_handler (registers* regs);
extern void irs0 ();
extern void irs1 ();

View File

@ -1,234 +1,63 @@
.code32
/*
* Interupt handlers
*/
.globl irs0
irs0:
cli
push $0
push $0
jmp irs_common
.macro ISR_NOERRORCODE NAME, VECTOR
.globl irs\NAME
irs\NAME:
cli
push $0
push \VECTOR
jmp irs_common
.endm
.globl irs1
irs1:
cli
push $0
push $1
jmp irs_common
.macro ISR_ERROCODE NAME, VECTOR
.globl irs\NAME
irs\NAME:
cli
push \VECTOR
jmp irs_common
.endm
.globl irs2
irs2:
cli
push $0
push $2
jmp irs_common
.globl irs3
irs3:
cli
push $0
push $3
jmp irs_common
ISR_NOERRORCODE 0 $0
ISR_NOERRORCODE 1 $1
ISR_NOERRORCODE 2 $2
ISR_NOERRORCODE 3 $3
ISR_NOERRORCODE 4 $4
ISR_NOERRORCODE 5 $5
ISR_NOERRORCODE 6 $6
ISR_NOERRORCODE 7 $7
ISR_NOERRORCODE 8 $8
ISR_NOERRORCODE 9 $9
ISR_NOERRORCODE 10 $10
ISR_NOERRORCODE 11 $11
ISR_NOERRORCODE 12 $12
ISR_NOERRORCODE 13 $13
ISR_NOERRORCODE 14 $14
ISR_NOERRORCODE 15 $15
ISR_NOERRORCODE 16 $16
ISR_NOERRORCODE 17 $17
ISR_NOERRORCODE 18 $18
ISR_NOERRORCODE 19 $19
ISR_NOERRORCODE 20 $20
ISR_NOERRORCODE 21 $21
ISR_NOERRORCODE 22 $22
ISR_NOERRORCODE 23 $23
ISR_NOERRORCODE 24 $24
ISR_NOERRORCODE 25 $25
ISR_NOERRORCODE 26 $26
ISR_NOERRORCODE 27 $27
ISR_NOERRORCODE 28 $28
ISR_NOERRORCODE 29 $29
ISR_NOERRORCODE 30 $30
ISR_NOERRORCODE 31 $31
.globl irs4
irs4:
cli
push $0
push $4
jmp irs_common
.globl irs5
irs5:
cli
push $0
push $5
jmp irs_common
.globl irs6
irs6:
cli
push $0
push $6
jmp irs_common
.globl irs7
irs7:
cli
push $0
push $7
jmp irs_common
.globl irs8
irs8:
cli
push $0
push $8
jmp irs_common
.globl irs9
irs9:
cli
push $0
push $9
jmp irs_common
.globl irs10
irs10:
cli
push $0
push $10
jmp irs_common
.globl irs11
irs11:
cli
push $0
push $11
jmp irs_common
.globl irs12
irs12:
cli
push $0
push $12
jmp irs_common
.globl irs13
irs13:
cli
push $13
jmp irs_common
.globl irs14
irs14:
cli
push $0
push $14
jmp irs_common
.globl irs15
irs15:
cli
push $0
push $15
jmp irs_common
.globl irs16
irs16:
cli
push $0
push $16
jmp irs_common
.globl irs17
irs17:
cli
push $0
push $17
jmp irs_common
.globl irs18
irs18:
cli
push $0
push $18
jmp irs_common
.globl irs19
irs19:
cli
push $0
push $19
jmp irs_common
.globl irs20
irs20:
cli
push $0
push $20
jmp irs_common
.globl irs21
irs21:
cli
push $0
push $21
jmp irs_common
.globl irs22
irs22:
cli
push $0
push $22
jmp irs_common
.globl irs23
irs23:
cli
push $0
push $23
jmp irs_common
.globl irs24
irs24:
cli
push $0
push $24
jmp irs_common
.globl irs25
irs25:
cli
push $0
push $25
jmp irs_common
.globl irs26
irs26:
cli
push $0
push $26
jmp irs_common
.globl irs27
irs27:
cli
push $0
push $27
jmp irs_common
.globl irs28
irs28:
cli
push $0
push $28
jmp irs_common
.globl irs29
irs29:
cli
push $0
push $29
jmp irs_common
.globl irs30
irs30:
cli
push $0
push $30
jmp irs_common
.globl irs31
irs31:
cli
push $0
push $31
jmp irs_common
irs_common:
pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov %ds, %ax
push %eax
@ -239,17 +68,20 @@ irs_common:
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %esp, %eax
push %eax
call irs_handler
pop %eax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
pop %ebx // reload ther orignal data segment descriptor
mov %bx, %ds
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
popa
add $8, %esp # cleans push error and irs code
sti
add $12, %esp # cleans push error and irs code
iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP

View File

@ -1,37 +1,46 @@
extern "C"{
#include "../lib/include/string.h"
extern "C"
{
#include "../lib/include/string.h"
}
#include "definitions.h"
#include "prekernel/bootstructure.h"
#include "drivers/vga/VBE.h"
#include "drivers/pit/pit.h"
#include "memory/memory.h"
#include "memory/memoryinfo.h"
#include "memory/memory.h"
#include "memory/VirtualMemoryManager.h"
#include "memory/KernelHeap.h"
#include "memory/gdt/gdtc.h"
#include "drivers/acpi/rsdp.h"
#include "drivers/ide/ide.h"
#include "drivers/ata/ataDevice.h"
#include "PartitionTable/MBR/MasterBootRecord.h"
#include "interrupts/idt/idt.h"
#include "filesystem/FAT/BiosParameterBlock.h"
#include "filesystem/FAT/DirectoryEntry.h"
#include "supervisorterminal/superVisorTerminal.h"
#include "drivers/io/io.h"
#include "drivers/vga/VBE.h"
#include "drivers/pci/pci.h"
#include "cpu.h"
#include "serial.h"
#include "time.h"
#include "drivers/pit/pit.h"
#include "terminal/kterm.h"
#include "supervisorterminal/superVisorTerminal.h"
#include "prekernel/multiboot.h"
#include "bootinfo.h"
extern "C" void kernel_main ();
void ProcessBootInfo();
#include "bootcheck.h"
#include "interrupts/idt/idt.h"
#include "time.h"
#include "cpu.h"
#include "serial.h"
#include "time.h"
#include "definitions.h"
/*
Copyright © Nigel Barink 2023
*/
extern "C" void kernel_main ()
{
@ -40,152 +49,6 @@ extern "C" void kernel_main ()
*/
printf("|=== BarinkOS ===|\n");
startSuperVisorTerminal();
RSDPTR* rsd = FindRSD();
RSDT* rsd_table = getRSDT(rsd);
// Enumerate the PCI bus
PCI_Enumerate();
TestIDEController();
int devNumber = 0 ;
for ( auto device : ide_devices){
if (!device.Reserved)
continue;
printf("Device %d\n" , devNumber);
printf (" Device on Channel: (0x%x) %s\n" ,device.Channel, device.Channel == 0 ? "Primary" : "Secondary");
printf (" Device drive:(0x%x) %s\n" , device.Drive, device.Drive? "Slave" : "Master");
printf (" Device Type:(0x%x) %s\n" , device.Type, device.Type ? "ATAPI" : "ATA");
devNumber ++;
}
enum BUS_PORT {
Primary= 0x1f0,
Secondary = 0x170
};
ATA_DEVICE::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER);
const int C = 0;
const int H = 0;
const int HPC = 16;
const int SPT = 63;
int S = 1;
uint32_t LBA = (C*HPC+H) * SPT + (S-1);
printf("LBA: %d\n" , LBA);
uint16_t buffer [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, buffer);
MBR* mbr = (MBR*) buffer;
printf("BootSector: 0x%x\n", mbr->ValidBootsector );
for( int i = 0 ; i < 4 ; i ++){
PartitionTableEntry PT = mbr->TableEntries[i];
printf("Partition %d [ %d sectors, PartitionType: %x, 0x%x, \nLBA Start: 0x%x ]\n" ,
i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start );
}
// Find the BiosParameter block
uint16_t biosparameterblock[256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mbr->TableEntries[0].LBA_partition_start, biosparameterblock);
BiosParameterBlock* bpb = (BiosParameterBlock*) biosparameterblock;
printf("\nBPB: Bytes per Sector %d\n", bpb->BytesPerSector );
printf("OEM ID: %s\n", bpb->OEM_id);
printf("Bytes per sector: %d\n", bpb->BytesPerSector);
printf("Sectors per cluster: %d\n", bpb->SectorsPerCluster);
printf("Reserved sectors: %d\n", bpb->ReservedSectors);
printf("Number of FAT: %d\n", bpb->NumberOfFileAllocationTables);
printf("Number of Dir entries: %d\n", bpb->NumberOfDirectoryEntries);
printf("Total Sectors in volume: %d\n", bpb->TotalSectorsInLogicalVolume);
printf("Sectors per FAT: %d\n", bpb->NumberOfSectorsPerFAT);
/**
* @brief File Allocation Table
*/
uint32_t FATAddress = mbr->TableEntries[0].LBA_partition_start + bpb->ReservedSectors ;
uint16_t FAT[256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, FATAddress, FAT );
// Show data in terminal
for(int i = 0; i < 256; i++ ) {
printf("%x ", FAT[i]);
}
kterm_put('\n');
uint32_t RootDirectoryRegion = FATAddress + ( bpb->NumberOfFileAllocationTables * bpb->NumberOfSectorsPerFAT );
uint32_t DataRegion = RootDirectoryRegion + ((bpb->NumberOfDirectoryEntries * 32) / bpb->BytesPerSector );
uint16_t data2 [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, RootDirectoryRegion, data2 );
DirectoryEntry* RootDirectory = (DirectoryEntry*) data2;
// List files in root
for(int i= 0; i < bpb->NumberOfDirectoryEntries ; i++ )
{
DirectoryEntry* entry = (DirectoryEntry*)((uint32_t) RootDirectory + (i * sizeof(DirectoryEntry)));
if( entry->filename[0] == (uint8_t) 0x00 )
break; // There are no more entries in this directory or the entry is free
if( entry->attribute & 0x01 == 0x01 || entry->attribute & 0x20 == 0x20)
continue; // Skip listing if hidden or Achieve flag is set
// Print the filename;
for( int n = 0; n < 8; n++ ){
if(entry->filename[n] == 0x20)
break;
kterm_put(entry->filename[n]);
}kterm_put('\n');
for( int n = 0; n < 3; n++){
kterm_put(entry->Extension[n]);
}kterm_put('\n');
printf("Attribute: %x \n" , entry->attribute);
printf("FileSize: %d Bytes\n", entry->FilesizeInBytes);
if( entry->FilesizeInBytes != 0x0 || entry->attribute & 0x8 == 0x0){
printf("Show contents");
printf( "Start cluster of the file: 0x%x\n" , entry->StartingCluster);
printf("IS it only 1 cluster? %s\n" , FAT[i] == 0xFFFF? "Yes": "No" );
uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02 ) * bpb->SectorsPerCluster);
uint16_t dataBlob [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, sector, dataBlob );
for( int n = 0; n < 256; n++)
{
kterm_put(dataBlob[n] & 0x00ff);
kterm_put(dataBlob[n] >> 8);
}kterm_put('\n');
}
printf("======================\n");
}
}
@ -198,38 +61,26 @@ extern "C" void early_main()
initGDT();
init_idt();
// Enable interrupts
asm volatile("STI");
initHeap();
printf("TRY ALLOCATING 4 BYTES\n");
uint32_t* MyVariable = (uint32_t*) malloc(4); // allocate 4 bytes using my heap
free(MyVariable);
// test heap allocation
struct KernelInfo {
int bar;
bool foo;
};
KernelInfo* MyInfo = (KernelInfo*) malloc(sizeof(KernelInfo));
MyInfo->bar = 6;
MyInfo->foo = false;
printf("bar contains %d\n", MyInfo->bar);
free(MyInfo);
initHeap();
printf("Enable Protected mode and jump to kernel main\n");
// Set the protected bit of control register 0
// this will put the CPU into protected mode
// NOTE: This should really be a assembly procedure
// We cant directly write to control register 0
// therefor we copy the value of control register 0 into eax
// once we are done manipulating the value we write the value in
// eax back to control register 0
asm volatile("mov %cr0, %eax ");
asm volatile("or $1, %eax");
asm volatile("mov %eax, %cr0"); // re-enable protected mode ?
asm volatile("mov %eax, %cr0");
pit_initialise();

View File

@ -1,43 +1,8 @@
#pragma once
extern "C"
{
#include "../lib/include/string.h"
}
#include "drivers/VGA/VBE.h"
#include "terminal/kterm.h"
#include "./boot/multiboot.h"
#include "bootinfo.h"
#include "memory/memory.h"
#include "memory/memoryinfo.h"
#include "bootcheck.h"
#include "gdt/gdtc.h"
#include "interrupts/idt/idt.h"
#include "drivers/IO/io.h"
#include "time.h"
#include "drivers/pit/pit.h"
#include "cpu.h"
#include "serial.h"
#include "drivers/IO/PCI/pci.h"
#include "drivers/ide/ide.h"
#include "./drivers/IO/ata/ataDevice.h"
#include "./PartitionTable/MBR/MasterBootRecord.h"
#include "./filesystem/FAT/BiosParameterBlock.h"
#include "./filesystem/FAT/ExtendBootRecord.h"
#include "./filesystem/FAT/DirectoryEntry.h"
#include "drivers/ACPI/rsdp.h"
#include "time.h"
#include "supervisorterminal/superVisorTerminal.h"
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
#define PANIC(message) {return;}

View File

@ -63,26 +63,24 @@ void free(void* addr)
void initHeap()
{
// put the start of our kernel heap 1 page after the kernel_end address
// Lets calculate the address
printf("FIND SUITABLE HEAP_ADDRESS\n");
uint32_t alligned_k_end = (uint32_t) &kernel_end + ((uint32_t)&kernel_end % BLOCK_SIZE == 0 ? 4096 : 0);
uint32_t HEAP_ADDRESS = (uint32_t) alligned_k_end + 4096;
printf("HEAP_ADDRESS: 0x%x\n", HEAP_ADDRESS);
// NOTE: we can't check if the mapping has failed or not here!
AllocatePage(HEAP_ADDRESS);
start = (heap_block*) HEAP_ADDRESS;
void* HEAP_ADDRESS = allocate_block();
printf("0x%x HEAP Paddr\n", HEAP_ADDRESS);
Immediate_Map((uint32_t)HEAP_ADDRESS + 0xC0000000, (uint32_t)HEAP_ADDRESS );
start = (heap_block*) ((uint32_t)HEAP_ADDRESS + 0xC0000000);
heap_size = 4096;
printf("Clear heap\n");
// Clear the heap
printf("set at 0x%x %d bytes to zero\n", start , heap_size);
memset((void*)start, 0x00, heap_size /4);
printf("Init first heap block\n");
// initialzie
start->Size = heap_size - sizeof(heap_block);
start->Used = false;
}

View File

@ -1,7 +1,8 @@
#include "VirtualMemoryManager.h"
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
extern uint32_t boot_page_directory[1024] ;
extern uint32_t boot_page_directory[1024] ; // points to the wrong location
extern uint32_t boot_page_table[1024];
@ -26,29 +27,28 @@ void AllocatePage(uint32_t vaddr)
{
printf("Directory entry is marked as present\n");
uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000) ;
page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset
printf("Page table address: 0x%x\n", (uint32_t)page_table);
//page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset
printf("Page table address: 0x%x\n", (uint32_t)&page_table);
// check if the page table entry is marked as present
if ( page_table[PageTableEntryIndex] & 0x1 )
{
printf("page already present!\n");
return;
} else{
printf("Mapping a physical page.\n");
// Map the entry to a physical page
page_table[PageTableEntryIndex] = (uint32_t)(allocate_block() + 0x3);
flush_cr3();
page_table[PageTableEntryIndex] = (uint32_t)allocate_block() | 0x3;
}
} else {
printf("Mapping a new page directory entry with a page table\n");
// mark the page table as present and allocate a physical block for it
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)(allocate_block() + 0x3);
flush_cr3();
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)allocate_block() | 0x3;
}
asm ("cli; invlpg (%0); sti" :: "r" (vaddr) : "memory" );
}
@ -74,12 +74,45 @@ void FreePage(uint32_t vaddr )
void Immediate_Map ( uint32_t vaddr, uint32_t paddr)
{
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
printf("map 0x%x to 0x%x\n", paddr, vaddr);
// allocate a page at virtual address
int PageDirectoryEntryIndex = vaddr >> 22;
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
printf("Map address at PDE 0x%x PTE 0x%x\n", PageDirectoryEntryIndex, PageTableEntryIndex);
if ((boot_page_directory - 0xC0000000)[PageDirectoryEntryIndex] & 0x1 )
{
printf("Directory entry is marked as present\n");
} else {
printf("Mapping a new page directory entry with a page table\n");
// mark the page table as present and allocate a physical block for it
void* new_page_dir = allocate_block();
printf("New page directory address 0x%x\n", new_page_dir);
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)new_page_dir | 0x3;
}
printf("PDE found at : 0x%x\n", (uint32_t) &boot_page_directory[PageDirectoryEntryIndex]);
uint32_t* page_table = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & 0xFFFFE000) ;
//page_table = (uint32_t*) ((uint32_t)page_table - 0xC0000000); // remove kernel offset
printf("Page table address: 0x%x\n", (uint32_t)page_table);
// check if the page table entry is marked as present
if ( page_table[PageTableEntryIndex] & 0x1 )
{
printf("page already present!\n");
printf("Entry found at addr: 0x%x\n", &(page_table[PageTableEntryIndex]));
} else{
printf("Mapping a physical page.\n");
// Map the entry to a physical page
page_table[PageTableEntryIndex] = (uint32_t)(paddr | 0x3);
}
asm ("cli; invlpg (%0); sti" :: "r" (vaddr) : "memory" );
}
void Immediate_Unmap(uint32_t vaddr)

View File

@ -9,7 +9,7 @@ void SetupVMM();
void AllocatePage(uint32_t v_addr );
void FreePage(uint32_t v_addr);
void Immediate_Map(uint32_t p_addr, uint32_t v_addr);
void Immediate_Map(uint32_t vaddr, uint32_t paddr);
void Immediate_Unmap (uint32_t v_addr);
// void Demand_map(uint32_t p_addr, uint32_t v_addr);

View File

@ -6,9 +6,13 @@
#define KERNEL_DATA_SEGMENT 2
#define USER_CODE_SEGMENT 3
#define USER_DATA_SEGMENT 4
#define TASK_STATE_SEGMENT 5
SegmentDescriptor GlobalDescriptorTable[5];
SegmentDescriptor GlobalDescriptorTable[6];
GlobalDescriptorTableDescriptor gdtDescriptor;
tss32 TaskStateSegment = {};
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){
GlobalDescriptorTable[which].base_low = (base & 0xFFFF );
@ -21,7 +25,6 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
GlobalDescriptorTable[which].granularity |= (granularity & 0xF0);
GlobalDescriptorTable[which].access = access;
}
@ -29,9 +32,9 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
void initGDT(){
#ifdef __VERBOSE__
printf("Init GDT!\n");
#endif
// NULL segment
add_descriptor(NULL_SEGMENT, 0,0,0,0);
@ -42,16 +45,18 @@ void initGDT(){
add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF);
// User Code Segment
// TODO:
add_descriptor(USER_CODE_SEGMENT, 0, 0xFFFFFFFF, 0xFA, 0xCF);
// User Data Segement
// TODO:
add_descriptor(USER_DATA_SEGMENT, 0, 0xFFFFFFFF, 0xF2, 0xCF);
// Task Segment Descriptor
add_descriptor(TASK_STATE_SEGMENT, (unsigned long)&TaskStateSegment, sizeof(TaskStateSegment), 0x89, 0x0);
// init Gdt Descriptor
gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
gdtDescriptor.base = (unsigned int) (&GlobalDescriptorTable);
printf("GDT at address 0x%x, with an size of 0x%x bytes\n" , (unsigned int)GlobalDescriptorTable, sizeof(GlobalDescriptorTable));
LoadGlobalDescriptorTable();

View File

@ -1,6 +1,5 @@
#pragma once
#include <stdint.h>
struct SegmentDescriptor {
unsigned short limit_low;
unsigned short base_low;
@ -10,14 +9,16 @@ struct SegmentDescriptor {
unsigned char base_high;
}__attribute__((packed));
struct tss32 {
uint64_t bits;
uint8_t other_bits :5;
}__attribute__((packed));
struct GlobalDescriptorTableDescriptor{
unsigned short limit;
unsigned int base;
}__attribute__((packed));
}__attribute__((packed)) ;
extern SegmentDescriptor GlobalDescriptorTable[];
extern GlobalDescriptorTableDescriptor gdtDescriptor;
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity );

View File

@ -1,4 +1,10 @@
#include "superVisorTerminal.h"
#include "../drivers/ata/ataDevice.h"
#include "../drivers/acpi/acpi.h"
#include "../drivers/ide/ide.h"
#include "../PartitionTable/MBR/MasterBootRecord.h"
#include "../filesystem/FAT/BiosParameterBlock.h"
#include "../filesystem/FAT/DirectoryEntry.h"
bool isRunning = true;
void startSuperVisorTerminal(){
while (isRunning){
@ -24,7 +30,7 @@ void startSuperVisorTerminal(){
}
printf("\n");
KeyHandled();
if ( strncmp("DATE", command , characterCount ) == 0 )
{
@ -34,7 +40,7 @@ void startSuperVisorTerminal(){
printf(" - Time: %02d:%02d:%02d\n" , hour, minute, second);
printf(" - Ticks: %09d\n", pit_tick);
}
else if( strncmp ("MEMORY" , command , characterCount) == 0 )
if( strncmp ("MEMORY" , command , characterCount) == 0 )
{
// Show memory layout
printf("========= Memory ==========\n");
@ -51,33 +57,181 @@ void startSuperVisorTerminal(){
//printf("Reserved Memory: %d bytes\n", bootinfo->memory->ReservedMemory);
}
else if(strncmp("TEST", command, characterCount) == 0)
if(strncmp("TEST", command, characterCount) == 0)
{
// TEST #DE exception
asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0
}
else if (strncmp("VERSION", command , characterCount) == 0)
if (strncmp("VERSION", command , characterCount) == 0)
{
// Show version information
printf("========= Version ========\n");
printf("Kernel v%d\n", 0);
}
else if(strncmp("CLEAR", command, characterCount) == 0)
if(strncmp("CLEAR", command, characterCount) == 0)
{
kterm_init();
printf("|=== BarinkOS ===|\n");
}
else if(strncmp("FAT", command, characterCount) == 0){
isRunning = false;
if(strncmp("FAT", command, characterCount) == 0)
{
printf("ACPI initialize!\n");
///ACPI::initialize();
// Enumerate the PCI bus
printf("PCI Enumeration\n");
PCI_Enumerate();
printf("TEST IDE Controller");
TestIDEController();
int devNumber = 0 ;
for ( auto device : ide_devices){
if (!device.Reserved)
continue;
printf("Device %d\n" , devNumber);
printf (" Device on Channel: (0x%x) %s\n" ,device.Channel, device.Channel == 0 ? "Primary" : "Secondary");
printf (" Device drive:(0x%x) %s\n" , device.Drive, device.Drive? "Slave" : "Master");
printf (" Device Type:(0x%x) %s\n" , device.Type, device.Type ? "ATAPI" : "ATA");
devNumber ++;
}
enum BUS_PORT {
Primary= 0x1f0,
Secondary = 0x170
};
ATA_DEVICE::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER);
const int C = 0;
const int H = 0;
const int HPC = 16;
const int SPT = 63;
int S = 1;
uint32_t LBA = (C*HPC+H) * SPT + (S-1);
printf("LBA: %d\n" , LBA);
uint16_t buffer [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, buffer);
MBR* mbr = (MBR*) buffer;
printf("BootSector: 0x%x\n", mbr->ValidBootsector );
for( int i = 0 ; i < 4 ; i ++){
PartitionTableEntry PT = mbr->TableEntries[i];
printf("Partition %d [ %d sectors, PartitionType: %x, 0x%x, \nLBA Start: 0x%x ]\n" ,
i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start );
}
// Find the BiosParameter block
uint16_t biosparameterblock[256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mbr->TableEntries[0].LBA_partition_start, biosparameterblock);
BiosParameterBlock* bpb = (BiosParameterBlock*) biosparameterblock;
printf("\nBPB: Bytes per Sector %d\n", bpb->BytesPerSector );
printf("OEM ID: %s\n", bpb->OEM_id);
printf("Bytes per sector: %d\n", bpb->BytesPerSector);
printf("Sectors per cluster: %d\n", bpb->SectorsPerCluster);
printf("Reserved sectors: %d\n", bpb->ReservedSectors);
printf("Number of FAT: %d\n", bpb->NumberOfFileAllocationTables);
printf("Number of Dir entries: %d\n", bpb->NumberOfDirectoryEntries);
printf("Total Sectors in volume: %d\n", bpb->TotalSectorsInLogicalVolume);
printf("Sectors per FAT: %d\n", bpb->NumberOfSectorsPerFAT);
/**
* @brief File Allocation Table
*/
uint32_t FATAddress = mbr->TableEntries[0].LBA_partition_start + bpb->ReservedSectors ;
uint16_t FAT[256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, FATAddress, FAT );
// Show data in terminal
for(int i = 0; i < 256; i++ ) {
printf("%x ", FAT[i]);
}
kterm_put('\n');
uint32_t RootDirectoryRegion = FATAddress + ( bpb->NumberOfFileAllocationTables * bpb->NumberOfSectorsPerFAT );
uint32_t DataRegion = RootDirectoryRegion + ((bpb->NumberOfDirectoryEntries * 32) / bpb->BytesPerSector );
uint16_t data2 [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, RootDirectoryRegion, data2 );
DirectoryEntry* RootDirectory = (DirectoryEntry*) data2;
// List files in root
for(int i= 0; i < bpb->NumberOfDirectoryEntries ; i++ )
{
DirectoryEntry* entry = (DirectoryEntry*)((uint32_t) RootDirectory + (i * sizeof(DirectoryEntry)));
if( entry->filename[0] == (uint8_t) 0x00 )
break; // There are no more entries in this directory or the entry is free
if( entry->attribute & 0x01 == 0x01 || entry->attribute & 0x20 == 0x20)
continue; // Skip listing if hidden or Achieve flag is set
// Print the filename;
for( int n = 0; n < 8; n++ ){
if(entry->filename[n] == 0x20)
break;
kterm_put(entry->filename[n]);
}kterm_put('\n');
for( int n = 0; n < 3; n++){
kterm_put(entry->Extension[n]);
}kterm_put('\n');
printf("Attribute: %x \n" , entry->attribute);
printf("FileSize: %d Bytes\n", entry->FilesizeInBytes);
if( entry->FilesizeInBytes != 0x0 || entry->attribute & 0x8 == 0x0){
printf("Show contents");
printf( "Start cluster of the file: 0x%x\n" , entry->StartingCluster);
printf("IS it only 1 cluster? %s\n" , FAT[i] == 0xFFFF? "Yes": "No" );
uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02 ) * bpb->SectorsPerCluster);
uint16_t dataBlob [256];
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, sector, dataBlob );
for( int n = 0; n < 256; n++)
{
kterm_put(dataBlob[n] & 0x00ff);
kterm_put(dataBlob[n] >> 8);
}kterm_put('\n');
}
printf("======================\n");
}
continue;
}
else
{
printf("Unknown command\n");
if(strncmp("glg", command, characterCount) == 0){
printf("Why???");
}
printf("executed command: %s\n", command);
delay(1000);
}
}