Started fleshing out the storage API

dev
Nigel Barink 2023-02-21 14:36:20 +01:00
parent 81f7351fe6
commit ef2bba5c1c
49 changed files with 661 additions and 475 deletions

View File

@ -55,4 +55,44 @@ int strncmp ( const char* str1, const char* str2, size_t num ){
}
return 0;
}
char* strchr(const char* s , int c){
while(*s) {
if(*s == c) return const_cast<char*>(s);
s++;
}
return NULL;
}
char* strtok(char* str, const char* delim , char**saveptr){
char *begin;
if(str) {
begin = str;
}
else if (*saveptr) {
begin = *saveptr;
}
else {
return NULL;
}
while(strchr(delim, begin[0])) {
begin++;
}
char *next = NULL;
for(int i = 0; i < strlen(delim); i++) {
char *temp = strchr(begin, delim[i]);
if(temp < next || next == NULL) {
next = temp;
}
}
if(!next) {
*saveptr = NULL;
return begin;
}
*next = 0;
*saveptr=next+1;
return begin;
}

View File

@ -9,4 +9,6 @@ int memcmp( const void* ptr1, const void* ptr2, size_t num);
size_t strlen(const char* str);
int strncmp ( const char* str1, const char* str2, size_t num );
int strncmp ( const char* str1, const char* str2, size_t num );
char* strtok(char* str, const char* delim , char**saveptr);

View File

@ -40,6 +40,10 @@ INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ)
all: build
clean:
rm $(OBJ_DIR)/* -r
build: $(OBJ_LINK_LIST)
$(CPP) -T linker.ld -o $(BUILD_DIR)/myos.bin -ffreestanding -ggdb -Og -nostdlib $(OBJ_LINK_LIST) -lgcc -L ../build/CoreLib -lCoreLib
@ -51,7 +55,7 @@ $(OBJ_DIR)/kterm.o:
$(CPP) -c terminal/kterm.cpp -o $(OBJ_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/io.o:
$(CPP) -c drivers/io/io.cpp -o $(OBJ_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c io/io.cpp -o $(OBJ_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/idt.o:
$(CPP) -c interrupts/idt.cpp -o $(OBJ_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti
@ -66,28 +70,28 @@ $(OBJ_DIR)/PhysicalMemoryManager.o:
$(CPP) -c memory/PhysicalMemoryManager.cpp -o $(OBJ_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/pci.o:
$(CPP) -c drivers/pci/pci.cpp -o $(OBJ_DIR)/pci.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c pci/pci.cpp -o $(OBJ_DIR)/pci.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/pcidevice.o:
$(CPP) -c drivers/pci/pciDevice.cpp -o $(OBJ_DIR)/pcidevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c pci/pciDevice.cpp -o $(OBJ_DIR)/pcidevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/atapiDevice.o:
$(CPP) -c drivers/atapi/atapiDevice.cpp -o $(OBJ_DIR)/atapiDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c storage/atapi/atapiDevice.cpp -o $(OBJ_DIR)/atapiDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/ataDevice.o:
$(CPP) -c drivers/ata/ataDevice.cpp -o $(OBJ_DIR)/ataDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c "storage/ata pio/ataDevice.cpp" -o $(OBJ_DIR)/ataDevice.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/rsdp.o:
$(CPP) -c drivers/acpi/rsdp.cpp -o $(OBJ_DIR)/rsdp.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c acpi/rsdp.cpp -o $(OBJ_DIR)/rsdp.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/acpi.o:
$(CPP) -c drivers/acpi/acpi.cpp -o $(OBJ_DIR)/acpi.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c acpi/acpi.cpp -o $(OBJ_DIR)/acpi.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/pit.o:
$(CPP) -c drivers/pit/pit.cpp -o $(OBJ_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/VFS.o:
$(CPP) -c vfs/VFS.cpp -o $(OBJ_DIR)/VFS.o $(CFLAGS) -fno-exceptions -fno-rtti
$(CPP) -c storage/vfs/VFS.cpp -o $(OBJ_DIR)/VFS.o $(CFLAGS) -fno-exceptions -fno-rtti
$(OBJ_DIR)/keyboard.o:
$(CPP) -c drivers/ps-2/keyboard.cpp -o $(OBJ_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti

35
kernel/acpi/acpi.cpp Normal file
View File

@ -0,0 +1,35 @@
#include "acpi.h"
RSDPDescriptor* ACPI::rsd_ptr;
RSDT* ACPI::rsd_table;
void ACPI::initialize(){
// Find the Root System Description Pointer
ACPI::rsd_ptr = FindRSD();
// is it valid
int sum = 0;
for (int i =0; i < 20 ; i++) {
sum += ((char*)rsd_ptr)[i];
}
printf(" 0x%x sum\n", sum);
return;
// Get the Root System Description Table
RSDT* rootSystemDescriptionTable = getRSDT((RSDPDescriptor *) rsd_ptr);
auto tableHeader = &rootSystemDescriptionTable->h;
// do checksum
sum = 0;
for(int i = 0; i < tableHeader->Length; i ++) {
sum += ((char*) tableHeader)[i];
}
if( sum != 0)
printf("Table invalid!");
}

View File

@ -8,6 +8,6 @@ class ACPI {
// doing more systems initialization
private:
static RSDPTR* rsd_ptr;
static RSDPDescriptor* rsd_ptr;
static RSDT* rsd_table;
};

View File

@ -1,6 +1,8 @@
#include "rsdp.h"
#include "../memory/VirtualMemoryManager.h"
void printRSD(RSDPTR* rsd){
void printRSD(RSDPDescriptor* rsd){
printf("Signature: ");
for(int i = 0; i < 8; i++){
kterm_put(rsd->signature[i]);
@ -17,29 +19,22 @@ void printRSD(RSDPTR* rsd){
printf("RSDT Address: 0x%x\n", rsd->RsdtAddress );
}
RSDPTR* FindRSD(){
char* memory_byte = (char*) 0xC00f2e14;
RSDPDescriptor* FindRSD(){
char* memory_byte = (char*) 0x000f2e14;
const void* string = "RSD PTR ";
for( ; (uint32_t) memory_byte < 0xC0100000; memory_byte+=10){
for( ; (uint32_t) memory_byte < 0x00100000; memory_byte+=10){
if( memcmp(memory_byte , string , 8 ) == 0 ) {
printf("RSD PTR found at 0x%x !\n", memory_byte);
break;
}
}
return (RSDPTR*) memory_byte;
return (RSDPDescriptor*) memory_byte;
}
RSDT* getRSDT(RSDPTR* rsd){
RSDT* getRSDT(RSDPDescriptor* rsd){
printf("rsdt Address: 0x%x\n", rsd->RsdtAddress);
return (RSDT*)rsd->RsdtAddress ;
RSDT* rsdt = (RSDT*) rsd->RsdtAddress;
printf("OEMID: ");
for(int i = 0; i < 6; i++){
kterm_put(rsdt->header.OEMID[i]);
}
kterm_put('\n');
return rsdt;
}

View File

@ -1,9 +1,9 @@
#pragma once
#include <stdint.h>
#include "./../../terminal/kterm.h"
#include "../terminal/kterm.h"
#include <CoreLib/Memory.h>
#include <stdint-gcc.h>
struct RSDPTR {
struct RSDPDescriptor {
char signature[8];
uint8_t Checksum ;
char OEMID [6];
@ -14,22 +14,22 @@ struct RSDPTR {
struct ACPISDTHeader{
char Signature[4];
uint32_t Length;
uint8_t Revision;
uint8_t CheckSum;
char OEMID[6];
char OEMTableID[8];
uint32_t OEMRevision;
uint32_t CreatorID;
uint32_t CreatorRevision;
}__attribute__((packed));
};
struct RSDT{
struct ACPISDTHeader header;
struct ACPISDTHeader h;
uint32_t PointerToSDT[]; // Length of array : (header.Length - sizeof(header))/ 4
}__attribute__((packed));
RSDPDescriptor* FindRSD();
RSDPTR* FindRSD();
void printRSD(RSDPDescriptor* rsd);
void printRSD(RSDPTR* rsd);
RSDT* getRSDT(RSDPTR* rsd);
RSDT* getRSDT(RSDPDescriptor* rsd);

View File

@ -0,0 +1,11 @@
//
// Created by nigel on 21/02/23.
//
#pragma once
class BlockDevice {
virtual char* Read()=0;
virtual void Write() =0;
};

View File

@ -0,0 +1,11 @@
//
// Created by nigel on 21/02/23.
//
#pragma once
class CharacterDevice {
virtual char Read()=0;
virtual void Write()=0;
};

View File

@ -1,15 +0,0 @@
#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((RSDPTR*)((uint32_t)rsd_ptr + 0xC00000000));
}

View File

@ -1,27 +0,0 @@
#pragma once
#include <stdint.h>
#include "../io/io.h"
#include "../ide/ideCommands.h"
#include "../ide/sampleIDE.definitions.h"
#include "../../terminal/kterm.h"
/*
* This first driver wil make use of IO ports.
* Doing so means reading or writing from disk is going
* to be very cpu intensive.
*/
enum DEVICE_DRIVE{
MASTER = 0xA0,
SLAVE = 0xB0
};
namespace ATA_DEVICE{
void Identify(uint16_t, DEVICE_DRIVE);
void Read (uint16_t, DEVICE_DRIVE, uint32_t, uint16_t*);
void Write(uint16_t, DEVICE_DRIVE);
void Soft_Reset(uint8_t ,DEVICE_DRIVE );
};

View File

@ -1,5 +1,7 @@
#pragma once
#include "../io/io.h"
#pragma once
#include <stdint-gcc.h>
#include "../../io/io.h"
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */

View File

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include "../io/io.h"
#include <stdint-gcc.h>
#include "../../io/io.h"
#define PIT_DATA_0 0x40
#define PIT_DATA_1 0x41
#define PIT_DATA_2 0x42

View File

@ -1,14 +1,14 @@
#pragma once
#include <stdint.h>
#include <stdint-gcc.h>
struct DirectoryEntry {
uint8_t filename [8];
uint8_t Extension [3];
uint8_t attribute;
uint8_t Reserved;
uint8_t creation;
uint16_t CreationTime;
uint16_t CreationDate;
uint8_t creation; // Creation in tenths of a second
uint16_t CreationTime; // Time Created NOTE: Multiply the seconds by 2
uint16_t CreationDate; // Date Created
uint16_t LastAccessDate;
uint16_t ReservedFAT32;
uint16_t LastWriteTime;
@ -16,4 +16,22 @@ struct DirectoryEntry {
uint16_t StartingCluster;
uint32_t FilesizeInBytes;
}__attribute__((packed));
}__attribute__((packed));
typedef struct _DIRECTORY{
uint8_t Filename[8];
uint8_t Ext[3];
uint8_t Attrib;
uint8_t Reserved;
uint8_t TimeCreatedMs;
uint16_t TimeCreated;
uint16_t DateCreated;
uint16_t DateLastAccessed;
uint16_t FirstClusterHiBytes;
uint16_t LastModTime;
uint16_t LastModDate;
uint16_t FirstCluster;
uint32_t FileSize;
}__attribute__((packed)) DIRECTORY, *PDIRECTORY;

View File

@ -1,109 +1,31 @@
#include "VFS.h"
#include "../filesystem/FAT/BiosParameterBlock.h"
#include "../drivers/ide/ide.h"
#include "../drivers/ata/ataDevice.h"
#include "../partitiontable/mbr/MasterBootRecord.h"
#include "../memory/KernelHeap.h"
#include "../../CoreLib/Memory.h"
#include "../filesystem/FAT/DirectoryEntry.h"
//
// Created by nigel on 21/02/23.
//
MOUNT_INFO mountInfo;
#include "FAT.h"
PFILESYSTEM _filesystems[DEVICE_MAX];
FILE volOpenFile(const char* fname)
{
if(fname){
unsigned char device = 'a';
char* filename = (char*) fname;
if(fname[1]== ':'){
device = fname[0];
filename += 2; // strip the volume component from the path
}
if(_filesystems[device - 'a']){
FILE file = _filesystems[device-'a']->Open(filename);
file.device = device;
return file;
}
}
FILE file;
file.flags = FS_INVALID;
return file;
}
extern void volReadFile(PFILE file, unsigned char* Buffer, unsigned int length)
void FAT::Read()
{
}
extern void volCloseFile(PFILE file)
void FAT::Open()
{
if( file->device < DEVICE_MAX){
// _filesystems[file->device]->Close(file);
}
}
extern void volRegisterFilesystem(PFILESYSTEM fsys , unsigned int deviceID){
if(deviceID < DEVICE_MAX)
if(fsys)
_filesystems[deviceID] = fsys;
}
extern void volUnregisterFilesystem(PFILESYSTEM){
}
extern void volUnregisterFileSystemByID(unsigned int deviceID){
void FAT::Write()
{
}
enum BUS_PORT {
Primary = 0x1f0,
Secondary = 0x170
};
void ParseDateInteger(unsigned int date){
printf("Date (hex) 0x%x\n", date);
unsigned int year = (date >> 9 )+ 1980;
unsigned int month = (date & 0xf0 ) >> 4;
unsigned int day = date & 0xf ;
printf("Date: (D,M,Y) %d, %d ,%d\n", day , month, year );
bool driveAvailable(){
int devNumber = 0;
for ( auto device : ide_devices){
if(!device.Reserved)
continue;
devNumber++;
}
// FIXME: If no drive is connected we continue trying to read from
// a not connected drive!
ATA_DEVICE::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER);
return true;
}
MBR* getPartitions(bool DEBUG = false){
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);
MBR* mbr =(MBR*) malloc(sizeof (MBR));
ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, (uint16_t*)mbr);
if(DEBUG){
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: 0x%x, 0x%x, \nLBA Start: 0x%x ]\n" ,
i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start );
}
}
return mbr;
}
BiosParameterBlock* getBPB(MBR* mbr, bool DEBUG =false ){
@ -142,6 +64,7 @@ uint16_t* ReadFAT (BiosParameterBlock& bpb , MBR& mbr, bool DEBUG = false ) {
return FAT;
}
void readFile(uint32_t DataRegion, DirectoryEntry* entry, uint16_t FATentry, BiosParameterBlock& bpb ){
printf("Show contents");
@ -161,6 +84,7 @@ void readFile(uint32_t DataRegion, DirectoryEntry* entry, uint16_t FATentry, Bio
}
kterm_put('\n');
}
void listFilesInRoot(MBR& mbr, BiosParameterBlock& bpb ){
auto FATAddress = mbr.TableEntries[0].LBA_partition_start + bpb.ReservedSectors;
uint32_t RootDirectoryRegion = FATAddress + ( bpb.NumberOfFileAllocationTables * bpb.NumberOfSectorsPerFAT );
@ -178,8 +102,12 @@ void listFilesInRoot(MBR& mbr, BiosParameterBlock& bpb ){
if (entry->filename[0] == (uint8_t) 0x00)
continue; // 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
if (entry->attribute & ATTRIBUTES::ATT_HIDDEN)
continue;
if(entry->attribute & ATTRIBUTES::ATTR_SYSTEM)
continue;
if(entry->attribute & ATTRIBUTES::ATTR_VOLUME_ID)
continue;
// Print the filename;
for (char n: entry->filename) {
@ -196,7 +124,7 @@ void listFilesInRoot(MBR& mbr, BiosParameterBlock& bpb ){
printf("Attribute: %x \n", entry->attribute);
printf("FileSize: %d Bytes\n", entry->FilesizeInBytes);
if (entry->FilesizeInBytes != 0x0 && (entry->attribute == 0x08)) {
if (entry->FilesizeInBytes != 0x0 && (entry->attribute != 0x10)) {
readFile(DataRegion,entry, FAT[i], bpb);
}
@ -205,8 +133,6 @@ void listFilesInRoot(MBR& mbr, BiosParameterBlock& bpb ){
}
/*
FILE fsysFatDirectory (const char* DirectoryName){
FILE file;
unsigned char* buf;
@ -248,7 +174,7 @@ FILE fsysFatDirectory (const char* DirectoryName){
return file;
}
*/
void fsysFATRead(PFILE file, unsigned char* buffer, unsigned int length){
if(file){
@ -294,7 +220,7 @@ void fsysFATRead(PFILE file, unsigned char* buffer, unsigned int length){
}
}
/*
FILE fsysFatOpenSubDir(FILE kFile, const char* filename){
FILE file;
@ -339,79 +265,3 @@ FILE fsysFatOpenSubDir(FILE kFile, const char* filename){
file.flags = FS_INVALID;
return file;
}
*/
void FileSystem::initialize()
{
MBR* mbr = getPartitions();
BiosParameterBlock* bootsector = getBPB(mbr);
listFilesInRoot(*mbr, *bootsector);
free(mbr);
free(bootsector);
/*
mountInfo.numSectors = bootsector->NumberOfSectorsPerFAT;
mountInfo.fatOffset = 1;
mountInfo.fatSize = bootsector->NumberOfSectorsPerFAT;
mountInfo.fatEntrySize = 8;
mountInfo.numRootEntries = bootsector->NumberOfDirectoryEntries;
mountInfo.rootOffset = (bootsector->NumberOfFileAllocationTables * bootsector->NumberOfSectorsPerFAT) + 1;
mountInfo.rootSize = (bootsector->NumberOfDirectoryEntries * 32) / bootsector->BytesPerSector;
*/
}
char* FindNextEntryName (char* path )
{
int length = strlen(path);
char* name = path;
int i = 0;
if( name[0] == '/')
i++;
while ( name[i] != '/' && i <= length)
i++;
char* s = (char*) malloc(i + 1 * sizeof(char));
for ( int a = 0; a < i; a++)
s[a] = path[a];
s[i + 1] = '\0';
return s;
}
void FileSystem::ResolvePath(Path &path)
{
// See reference material (1) https://man7.org/linux/man-pages/man7/path_resolution.7.html
char* string_path = path.str();
void* cpy = string_path;
bool isAbsolutePath = string_path[0] == '/';
if(isAbsolutePath)
{
// strip the first slash
string_path++;
}
char* entry_name = FindNextEntryName(string_path);
printf("Look for entry with name: %s\n", entry_name);
int skip = strlen(entry_name);
free(entry_name);
entry_name = FindNextEntryName(string_path + skip);
printf("Look for entry with name: %s\n", entry_name);
skip = strlen(entry_name);
free(entry_name);
free(cpy);
}

View File

@ -0,0 +1,41 @@
//
// Created by nigel on 21/02/23.
//
#pragma once
#include "ExtendBootRecord.h"
#include "BiosParameterBlock.h"
#include "DirectoryEntry.h"
// Date Format
// [0..4] Day
// [5..8] Month
// [9..15] Year
// Time Format
// [0..4] Seconds
// [5..10] Minute
// [11..15] Hour
class FAT {
public:
void Open();
void Read();
void Write();
private:
enum struct TYPE{
FAT,
FAT16,
FAT32,
VFAT
};
enum ATTRIBUTES {
ATTR_READ_ONLY = 0x01,
ATT_HIDDEN = 0x02,
ATTR_SYSTEM = 0x04,
ATTR_VOLUME_ID = 0x08,
ATTR_DIRECTORY = 0x10,
ATTR_ARCHIVE = 0x20
};
};

View File

@ -7,14 +7,15 @@
#include "memory/TaskStateSegment.h"
#include "supervisorterminal/superVisorTerminal.h"
#include "drivers/vga/VBE.h"
#include "drivers/pci/pci.h"
#include "pci/pci.h"
#include "drivers/pit/pit.h"
#include "drivers/acpi/acpi.h"
#include "acpi/acpi.h"
#include "i386/processor.h"
#include "terminal/kterm.h"
#include "interrupts/idt.h"
#include "serial.h"
#include "vfs/VFS.h"
#include "storage/vfs/VFS.h"
#include "../CoreLib/Memory.h"
extern "C" void LoadGlobalDescriptorTable();
extern "C" void jump_usermode();
@ -25,6 +26,7 @@ extern "C" void kernel ()
init_serial();
kterm_init();
setup_tss();
initGDT();
initidt();
@ -37,16 +39,13 @@ extern "C" void kernel ()
initHeap();
pit_initialise();
// ACPI::initialize(); // FIXME: improper reading of bios memory
PCI::Scan();
ACPI::initialize();
//PCI::Scan();
processor::initialize();
processor::enable_protectedMode();
FileSystem::initialize();
// Testing my path resolution functions
Path test = Path("/boot/myos.bin");
FileSystem::ResolvePath(test);
VirtualFileSystem::initialize();
#ifdef USERMODE_RELEASE

View File

@ -25,6 +25,7 @@ SECTIONS
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
{
*(.rodata)
*(.symtab)
}
.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
{
@ -36,6 +37,8 @@ SECTIONS
*(.bss)
*(.bootstrap_stack)
}
_kernel_end = .;
kernel_end = .; /* For legacy reasons */
}

View File

@ -1,6 +1,8 @@
#pragma once
#include <stdint.h>
#include <stdint-gcc.h>
#include "PartitionTableEntry.h"
#include "../../memory/KernelHeap.h"
#include "../../storage/ata pio/ataDevice.h"
struct MBR {
uint8_t code [440];
@ -8,4 +10,31 @@ struct MBR {
uint16_t Reserved;
PartitionTableEntry TableEntries[4];
uint16_t ValidBootsector;
}__attribute__((packed));
}__attribute__((packed));
MBR* getPartitions( bool DEBUG = false){
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);
MBR* mbr =(MBR*) malloc(sizeof (MBR));
ATAPIO::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, (uint16_t*)mbr);
if(DEBUG){
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: 0x%x, 0x%x, \nLBA Start: 0x%x ]\n" ,
i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start );
}
}
return mbr;
}

View File

@ -1,7 +1,7 @@
#pragma once
#include <stdint.h>
#include "../io/io.h"
#include "../../terminal/kterm.h"
#include "../terminal/kterm.h"
#include "pciDevice.h"
// Configuration Space Access Mechanism #1

View File

@ -6,7 +6,7 @@
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
#define VADDR_TO_PADDR(vaddr) (vaddr - 0xC0000000)
#define PADDR_TO_VADDR(paddr) (paddr + 0xC0000000)
multiboot_info_t* global_mbi;
extern "C" void prekernelSetup ( unsigned long magic, multiboot_info_t* mbi)
{
@ -21,8 +21,8 @@ extern "C" void prekernelSetup ( unsigned long magic, multiboot_info_t* mbi)
}
mbi = PADDR_TO_VADDR(mbi);
global_mbi = mbi;
// Setup the physical memory manager immmediatly
// Doing so saves the complications of doing it later when
// paging is enabled

View File

@ -1,7 +1,7 @@
#pragma once
#include "terminal/kterm.h"
#include "drivers/io/io.h"
#include "io/io.h"
#define PORT 0x3f8
static int init_serial() {

View File

@ -1,112 +1,9 @@
#include "ataDevice.h"
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
#include "../../io/io.h"
void ATA_DEVICE::Soft_Reset(uint8_t DEVICE_CHANNEL,DEVICE_DRIVE drive){
printf("Soft reseting drive...\n");
outb(channels[DEVICE_CHANNEL].base + 7 , 0x4);
// wait a bit..
for(int i = 0 ; i < 1000000; i++){
asm volatile("NOP");
}
outb(channels[DEVICE_CHANNEL].base + 7 , 0x0);
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
}
void ATA_DEVICE::Identify(uint16_t DEVICE_CHANNEL,DEVICE_DRIVE drive ){
// lets ignore which port we actually want to check for now !
/*
THE STEPS INVOLVED
1. Select the target drive by sending master (0x0A) or slave (0x0B) to the
drive select IO port
2. Set the Sectorcount, LBAlo, LBAmid and LBAhi IO ports to 0
3. Send the identify command (0xEC) to the command IO port
4. Read the status port
4.2 If the value is 0x0 the drive does not exist
4.3 If it has any other value continue
5. poll the status port until bit 7 is clear.
6. Check if the LBAmid and LBAhi ports are non-zero
6.2. If non-zero stop polling this is not an ATA device
6.3 If zero continue
7. poll status port until bit 3 is set or bit 0 is set
8. if err is clear, read the data from the data port
*/
//printf("channel selected: 0x%x", DEVICE_CHANNEL);
// Assuming Master here
// Select the target drive
outb(DEVICE_CHANNEL | 6, drive); // on the primary bus select the master drive
outb(DEVICE_CHANNEL | 6 , 0x0); // write 0 to the controlport for some reason
outb(DEVICE_CHANNEL | 6, drive);
uint8_t status = inb(DEVICE_CHANNEL | 7 );
if(status == 0x00){
printf("No drive\n");
return;
}
// send the identify command;
outb(DEVICE_CHANNEL | 7, 0xEC);
// set the sectorCount, LBAlo, LBAmid, LBA,hi IO ports to 0
outb(DEVICE_CHANNEL | 2, 0);
outb(DEVICE_CHANNEL | 3, 0);
outb(DEVICE_CHANNEL | 4, 0);
outb(DEVICE_CHANNEL | 5, 0);
// send the identify command ;
//printf("command sent!\n");
outb(DEVICE_CHANNEL | 7 , 0xEC);
// read the status port
uint8_t status2 = inb(DEVICE_CHANNEL | 7);
if( status2 == 0x00){
printf("No drive\n");
return;
}
//printf("Waiting until ready...\n");
while(((status2 & 0x80 == 0x80)
&& (status2 & 0x01) != 0x01)
) status2 = inb(DEVICE_CHANNEL | 7);
if( status2 & 0x01){
printf("Error!\n");
return ;
}
uint16_t deviceIdentify [256] = {0};
for ( int i = 0; i < 256; i++){
uint16_t data;
asm volatile ("inw %1, %0" : "=a"(data): "Nd"(DEVICE_CHANNEL));
deviceIdentify[i] = data;
}
printf("Model-label (ASCII hex): ");
for(int i = 27; i < 47; i++){
kterm_put((char)(deviceIdentify[i] >> 8));
kterm_put((char)(deviceIdentify[i] & 0x00FF));
}
kterm_put('\n');
}
void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive, uint32_t LBA, uint16_t* buffer) {
void ATAPIO::Read(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive, uint32_t LBA, uint16_t* buffer) {
/*
Assume you have a sectorcount byte and a 28 bit LBA value. A sectorcount of 0 means 256 sectors = 128K.
@ -188,6 +85,116 @@ void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive, uint32_t LBA
}
void ATA_DEVICE::Write(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
void ATAPIO::Write(uint16_t data, DEVICE_DRIVE dev){
printf("Not implemented\n");
}
}
void ATAPIO::Identify(uint16_t DEVICE_CHANNEL,DEVICE_DRIVE drive ){
// lets ignore which port we actually want to check for now !
/*
THE STEPS INVOLVED
1. Select the target drive by sending master (0x0A) or slave (0x0B) to the
drive select IO port
2. Set the Sectorcount, LBAlo, LBAmid and LBAhi IO ports to 0
3. Send the identify command (0xEC) to the command IO port
4. Read the status port
4.2 If the value is 0x0 the drive does not exist
4.3 If it has any other value continue
5. poll the status port until bit 7 is clear.
6. Check if the LBAmid and LBAhi ports are non-zero
6.2. If non-zero stop polling this is not an ATA device
6.3 If zero continue
7. poll status port until bit 3 is set or bit 0 is set
8. if err is clear, read the data from the data port
*/
//printf("channel selected: 0x%x", DEVICE_CHANNEL);
// Assuming Master here
// Select the target drive
outb(DEVICE_CHANNEL | 6, drive); // on the primary bus select the master drive
outb(DEVICE_CHANNEL | 6 , 0x0); // write 0 to the controlport for some reason
outb(DEVICE_CHANNEL | 6, drive);
uint8_t status = inb(DEVICE_CHANNEL | 7 );
if(status == 0x00){
printf("No drive\n");
return;
}
// send the identify command;
outb(DEVICE_CHANNEL | 7, 0xEC);
// set the sectorCount, LBAlo, LBAmid, LBA,hi IO ports to 0
outb(DEVICE_CHANNEL | 2, 0);
outb(DEVICE_CHANNEL | 3, 0);
outb(DEVICE_CHANNEL | 4, 0);
outb(DEVICE_CHANNEL | 5, 0);
// send the identify command ;
//printf("command sent!\n");
outb(DEVICE_CHANNEL | 7 , 0xEC);
// read the status port
uint8_t status2 = inb(DEVICE_CHANNEL | 7);
if( status2 == 0x00){
printf("No drive\n");
return;
}
//printf("Waiting until ready...\n");
while(((status2 & 0x80 == 0x80)
&& (status2 & 0x01) != 0x01)
) status2 = inb(DEVICE_CHANNEL | 7);
if( status2 & 0x01){
printf("Error!\n");
return ;
}
uint16_t deviceIdentify [256] = {0};
for ( int i = 0; i < 256; i++){
uint16_t data;
asm volatile ("inw %1, %0" : "=a"(data): "Nd"(DEVICE_CHANNEL));
deviceIdentify[i] = data;
}
printf("Model-label (ASCII hex): ");
for(int i = 27; i < 47; i++){
kterm_put((char)(deviceIdentify[i] >> 8));
kterm_put((char)(deviceIdentify[i] & 0x00FF));
}
kterm_put('\n');
}
void ATAPIO::Soft_Reset(uint8_t DEVICE_CHANNEL,DEVICE_DRIVE drive){
printf("Soft reseting drive...\n");
// outb(channels[DEVICE_CHANNEL].base + 7 , 0x4);
// wait a bit..
for(int i = 0 ; i < 1000000; i++){
asm volatile("NOP");
}
//outb(channels[DEVICE_CHANNEL].base + 7 , 0x0);
}

View File

@ -0,0 +1,38 @@
#pragma once
#include <stdint-gcc.h>
#include "../ide/ideCommands.h"
#include "../ide/sampleIDE.definitions.h"
#include "../../devices/BlockDevice.h"
#include "../../terminal/kterm.h"
/*
* This first driver wil make use of IO ports.
* Doing so means reading or writing from disk is going
* to be very cpu intensive.
*/
enum DEVICE_DRIVE{
MASTER = 0xA0,
SLAVE = 0xB0
};
enum BUS_PORT {
Primary = 0x1f0,
Secondary = 0x170
};
class ATAPIO
{
public:
static void Identify(uint16_t, DEVICE_DRIVE);
static void Read (uint16_t, DEVICE_DRIVE, uint32_t, uint16_t*);
static void Write(uint16_t, DEVICE_DRIVE);
static void Soft_Reset(uint8_t ,DEVICE_DRIVE );
};

View File

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include "../io/io.h"
#include "../../io/io.h"
#include "../ide/ideCommands.h"
#include "../ide/sampleIDE.definitions.h"

View File

@ -1,10 +1,10 @@
#pragma once
#include <stdint.h>
#include "../pci/pciDevice.h"
#include "../pci/pci.h"
#include <stdint-gcc.h>
#include "../../terminal/kterm.h"
#include "ideCommands.h"
#include "sampleIDE.h"
#include "../../pci/pciDevice.h"
#include "../../pci/pci.h"
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)

View File

@ -1,5 +1,5 @@
#pragma once
#include <stdint.h>
#include <stdint-gcc.h>
#include "../../terminal/kterm.h"
#include "sampleIDE.definitions.h"
#include "ideCommands.h"
@ -239,4 +239,20 @@ inline void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t
channels[ATA_PRIMARY ].bmide = (BAR4 & (~1)) + 0; // Bus Master IDE
channels[ATA_SECONDARY].bmide = (BAR4 & (~1)) + 8; // Bus Master IDE
}
bool driveAvailable(){
int devNumber = 0;
for ( auto device : ide_devices){
if(!device.Reserved)
continue;
devNumber++;
}
// FIXME: If no drive is connected we continue trying to read from
// a not connected drive!
//ATAPIO::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER);
return true;
}

View File

@ -0,0 +1,41 @@
//
// Created by nigel on 21/02/23.
//
#include "FileSystem.h"
void FileSystem::WriteFile(int file, unsigned char* buffer, unsigned int length) {
}
void FileSystem::ReadFile(int file, unsigned char* buffer, unsigned int length) {
}
FILE FileSystem::OpenFile(const char* fname){
if(fname){
unsigned char device = 'a';
char* filename = (char*) fname;
if(fname[1]== ':'){
device = fname[0];
filename += 2; // strip the volume component from the path
}
if(_filesystems[device - 'a']){
FILE file = _filesystems[device-'a']->Open(filename);
file.device = device;
return file;
}
}
FILE file;
file.flags = FS_INVALID;
return file;
}
void FileSystem::CloseFile(PFILE file) {
if(file->device < DEVICE_MAX){
// _filesystems[file->device]->Close(file);
}
}

View File

@ -0,0 +1,18 @@
//
// Created by nigel on 21/02/23.
//
#pragma once
#include "StorageTypes.h"
class FileSystem {
public:
static void WriteFile(PFILE file, unsigned char* beffer, unsigned int length);
static void ReadFile(PFILE file, unsigned char* buffer, unsigned int length);
static FILE OpenFile(const char* fname);
static void CloseFile(PFILE file);
};

View File

@ -0,0 +1,5 @@
//
// Created by nigel on 21/02/23.
//
#include "Inode.h"

View File

@ -0,0 +1,24 @@
//
// Created by nigel on 21/02/23.
//
#pragma once
enum struct NODE_TYPE {
FILESYSTEM,
FILE,
DIRECTORY
};
enum struct PERMISSIONS {
READ,
WRITE,
EXECUTE
};
struct Inode {
NODE_TYPE type;
PERMISSIONS permissions;
Inode* Parent;
Inode* sibling;
};

View File

@ -0,0 +1,32 @@
//
// Created by nigel on 21/02/23.
//
#pragma once
#include <stdint-gcc.h>
enum FS_TYPES {
FS_FILE =0,
FS_DIRECTORY =1,
FS_INVALID=2
};
typedef struct _FILE {
char name [32];
uint32_t flags;
uint32_t filelength;
uint32_t id;
uint32_t eof;
uint32_t position;
uint32_t currentCluster;
uint32_t device;
}FILE, *PFILE;
typedef struct _FILE_SYSTEM{
char name[8];
FILE (*Directory) (const char* Directoryname);
void (*Mount) ();
void (*Read) (PFILE file, unsigned char* buffer, unsigned int length);
void (Close) (PFILE);
FILE (*Open) (const char* filename);
}FILESYSTEM, *PFS;

View File

@ -0,0 +1,54 @@
#include "VFS.h"
#include <stdint-gcc.h>
#include "../../memory/KernelHeap.h"
#include <CoreLib/Memory.h>
PFS VirtualFileSystem::_filesystems[VirtualFileSystem::DEVICE_MAX];
void VirtualFileSystem::initialize()
{
}
void VirtualFileSystem::ResolvePath(Path &path)
{
// See reference material (1) https://man7.org/linux/man-pages/man7/path_resolution.7.html
char* string_path = path.str();
void* cpy = string_path;
bool isAbsolutePath = string_path[0] == '/';
if(isAbsolutePath)
{
// strip the first slash
string_path++;
}
char* tokstate = NULL;
char* nextdir = strtok(string_path, "/", &tokstate);
while (nextdir)
{
printf("First entry to look for: %s\n", nextdir);
nextdir = strtok(NULL, "/", &tokstate);
}
free(cpy);
}
void VirtualFileSystem::Mount(PFS filesystemDescriptor, unsigned int DeviceID)
{
if(DeviceID < DEVICE_MAX)
if(filesystemDescriptor)
_filesystems[DeviceID] = filesystemDescriptor;
}
void VirtualFileSystem::Unmount(unsigned int DeviceID) {
if(DeviceID < DEVICE_MAX)
_filesystems[DeviceID] = nullptr;
}

17
kernel/storage/vfs/VFS.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <stdint-gcc.h>
#include "../../../CoreLib/Path.h"
#include "StorageTypes.h"
class VirtualFileSystem
{
public:
static void initialize();
static void Mount(PFS fs, unsigned int DeviceID);
static void Unmount(unsigned int DeviceID);
static void ResolvePath(Path& path);
private:
static const unsigned int DEVICE_MAX = 26;
static PFS _filesystems[DEVICE_MAX];
};

View File

@ -1,8 +1,9 @@
#include "superVisorTerminal.h"
#include "../drivers/ata/ataDevice.h"
#include "../storage/ata pio/ataDevice.h"
#include "../partitiontable/mbr/MasterBootRecord.h"
#include "../filesystem/FAT/BiosParameterBlock.h"
#include "../filesystem/FAT/DirectoryEntry.h"
bool isRunning = true;
extern "C" void startSuperVisorTerminal()
{

View File

@ -1,10 +1,10 @@
#pragma once
#include <stdint.h>
#include <stdint-gcc.h>
#include <stddef.h>
#include <stdbool.h>
#include "../drivers/vga/colors.h"
#include "../drivers/io/io.h"
#include "../io/io.h"
#include <CoreLib/Memory.h>
void kterm_init();

View File

@ -1,5 +1,5 @@
#pragma once
#include "drivers/io/io.h"
#include "io/io.h"
#define CURRENT_YEAR 2021

View File

@ -1,6 +1,6 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdint-gcc.h>
void init_timer (uint32_t frequency);

View File

@ -1,80 +0,0 @@
#pragma once
#include <stdint.h>
#include "../../CoreLib/Path.h"
#define FS_FILE 0
#define FS_DIRECTORY 1
#define FS_INVALID 2
#define DEVICE_MAX 26
typedef struct _FILE {
char name [32];
uint32_t flags;
uint32_t filelength;
uint32_t id;
uint32_t eof;
uint32_t position;
uint32_t currentCluster;
uint32_t device;
}FILE, *PFILE;
typedef struct _FILE_SYSTEM{
char name[8];
FILE (*Directory) (const char* Directoryname);
void (*Mount) ();
void (*Read) (PFILE file, unsigned char* buffer, unsigned int length);
void (Close) (PFILE);
FILE (*Open) (const char* filename);
}FILESYSTEM, *PFILESYSTEM;
typedef struct _MOUNT_INFO{
uint32_t numSectors;
uint32_t fatOffset;
uint32_t numRootEntries;
uint32_t rootOffset;
uint32_t rootSize;
uint32_t fatSize;
uint32_t fatEntrySize;
}MOUNT_INFO, *PMOUNT_INFO;
typedef struct _DIRECTORY{
uint8_t Filename[8];
uint8_t Ext[3];
uint8_t Attrib;
uint8_t Reserved;
uint8_t TimeCreatedMs;
uint16_t TimeCreated;
uint16_t DateCreated;
uint16_t DateLastAccessed;
uint16_t FirstClusterHiBytes;
uint16_t LastModTime;
uint16_t LastModDate;
uint16_t FirstCluster;
uint32_t FileSize;
}DIRECTORY, *PDIRECTORY;
// Date Format
// [0..4] Day
// [5..8] Month
// [9..15] Year
// Time Format
// [0..4] Seconds
// [5..10] Minute
// [11..15] Hour
extern PFILESYSTEM _filesystems[DEVICE_MAX];
FILE volOpenFile(const char* fname);
void volCloseFile(PFILE file);
void volRegisterFilesystem(PFILESYSTEM, unsigned int deviceID);
void volUnregisterFilesystem(PFILESYSTEM);
void volUnregisterFileSystemByID(unsigned int deviceID);
class FileSystem{
public:
static void initialize();
static void ResolvePath(Path& path);
};

12
run.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
cd CoreLib
make
cd ../kernel
make clean
make
cd ..
./scripts/update_harddrive.sh
./scripts/run_qemu.sh

View File

@ -1,4 +1,7 @@
#!/bin/bash
echo "running in cwd : "
echo $(pwd)
echo "Mount harddrive image as block device"
sudo losetup /dev/loop9 disk.img
sudo mount /dev/loop9 /mnt