Merge into main the new state of the operating system/kernel #1
@ -56,3 +56,43 @@ 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;
|
||||
}
|
@ -10,3 +10,5 @@ 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 );
|
||||
|
||||
char* strtok(char* str, const char* delim , char**saveptr);
|
@ -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
35
kernel/acpi/acpi.cpp
Normal 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!");
|
||||
}
|
@ -8,6 +8,6 @@ class ACPI {
|
||||
// doing more systems initialization
|
||||
|
||||
private:
|
||||
static RSDPTR* rsd_ptr;
|
||||
static RSDPDescriptor* rsd_ptr;
|
||||
static RSDT* rsd_table;
|
||||
};
|
@ -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;
|
||||
}
|
@ -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);
|
11
kernel/devices/BlockDevice.h
Normal file
11
kernel/devices/BlockDevice.h
Normal file
@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by nigel on 21/02/23.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
class BlockDevice {
|
||||
virtual char* Read()=0;
|
||||
virtual void Write() =0;
|
||||
};
|
||||
|
||||
|
11
kernel/devices/CharacterDevice.h
Normal file
11
kernel/devices/CharacterDevice.h
Normal file
@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by nigel on 21/02/23.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
class CharacterDevice {
|
||||
virtual char Read()=0;
|
||||
virtual void Write()=0;
|
||||
};
|
||||
|
||||
|
@ -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));
|
||||
}
|
@ -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 );
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include "../io/io.h"
|
||||
|
||||
#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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
@ -17,3 +17,21 @@ struct DirectoryEntry {
|
||||
uint32_t FilesizeInBytes;
|
||||
|
||||
}__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;
|
@ -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);
|
||||
|
||||
}
|
41
kernel/filesystem/FAT/FAT.h
Normal file
41
kernel/filesystem/FAT/FAT.h
Normal 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
|
||||
};
|
||||
};
|
@ -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
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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];
|
||||
@ -9,3 +11,30 @@ struct MBR {
|
||||
PartitionTableEntry TableEntries[4];
|
||||
uint16_t ValidBootsector;
|
||||
}__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;
|
||||
}
|
||||
|
@ -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
|
@ -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,7 +21,7 @@ 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
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -1,18 +1,97 @@
|
||||
#include "ataDevice.h"
|
||||
#include "../../io/io.h"
|
||||
|
||||
#define IS_BIT_SET(x, bit) ((x >> bit & 0x1) == 1)
|
||||
|
||||
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");
|
||||
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.
|
||||
|
||||
Notes: - When you send a command byte and the RDY bit of the Status Registers is clear, you may have to wait (technically up to 30 seconds) for the drive to spin up, before DRQ sets. You may also need to ignore ERR and DF the first four times that you read the Status, if you are polling.
|
||||
- for polling PIO drivers: After transferring the last uint16_t of a PIO data block to the data IO port, give the drive a 400ns delay to reset its DRQ bit (and possibly set BSY again, while emptying/filling its buffer to/from the drive).
|
||||
- on the "magic bits" sent to port 0x1f6: Bit 6 (value = 0x40) is the LBA bit. This must be set for either LBA28 or LBA48 transfers. It must be clear for CHS transfers. Bits 7 and 5 are obsolete for current ATA drives, but must be set for backwards compatibility with very old (ATA1) drives.
|
||||
|
||||
An example of a 28 bit LBA PIO mode read on the Primary bus:
|
||||
|
||||
*/
|
||||
|
||||
const int sectorCount = 1;
|
||||
|
||||
// Floating bus check
|
||||
uint8_t floatingBus = inb(DEVICE_CHANNEL | 7);
|
||||
if (floatingBus == 0xFF){
|
||||
printf("Floating bus!!");
|
||||
return ;
|
||||
}
|
||||
outb(channels[DEVICE_CHANNEL].base + 7 , 0x0);
|
||||
|
||||
//printf("Read LBA: 0x%x\n", LBA);
|
||||
// Send 0xE0 for the "master" or 0xF0 for the "slave", ORed with the highest 4 bits of the LBA to port 0x1F6: outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F))
|
||||
outb(DEVICE_CHANNEL | 6 , ( 0xE0 | (LBA >>28) ) );
|
||||
// Send a NULL byte to port 0x1F1, if you like (it is ignored and wastes lots of CPU time): outb(0x1F1, 0x00)
|
||||
outb(DEVICE_CHANNEL | 1, 0x0000 );
|
||||
//Send the sectorcount to port 0x1F2: outb(0x1F2, (unsigned char) count)
|
||||
outb(DEVICE_CHANNEL | 2, sectorCount);
|
||||
//Send the low 8 bits of the LBA to port 0x1F3: outb(0x1F3, (unsigned char) LBA))
|
||||
outb(DEVICE_CHANNEL | 3, LBA);
|
||||
//Send the next 8 bits of the LBA to port 0x1F4: outb(0x1F4, (unsigned char)(LBA >> 8))
|
||||
outb(DEVICE_CHANNEL | 4, (LBA >> 8));
|
||||
//Send the next 8 bits of the LBA to port 0x1F5: outb(0x1F5, (unsigned char)(LBA >> 16))
|
||||
outb(DEVICE_CHANNEL | 5, (LBA >> 16));
|
||||
//Send the "READ SECTORS" command (0x20) to port 0x1F7: outb(0x1F7, 0x20)
|
||||
outb(DEVICE_CHANNEL | 7, 0x20);
|
||||
|
||||
volatile int i,j;
|
||||
for(i=0;i<2000;i++)
|
||||
for(j=0;j<25000;j++)
|
||||
asm("NOP");
|
||||
|
||||
//Wait for an IRQ or poll.
|
||||
uint8_t status = inb(DEVICE_CHANNEL | 7);
|
||||
if( status == 0x00){
|
||||
printf("No drive\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//printf("Status: %x\n", status);
|
||||
// Check if busy!
|
||||
while((status & 0x80) == 0x80){
|
||||
printf("Reading....\r");
|
||||
status = inb(DEVICE_CHANNEL | 7);
|
||||
}
|
||||
|
||||
|
||||
if ((status & 0x01) == 0x01){
|
||||
printf("Error occured during read!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//Transfer 256 16-bit values, a uint16_t at a time, into your buffer from I/O port 0x1F0.
|
||||
if( status & 0x01){
|
||||
printf("Error!\n");
|
||||
printf("Status: 0x%x\n", status);
|
||||
uint16_t error_register = inb(DEVICE_CHANNEL | 1);
|
||||
printf("Error register 0x%x\n",error_register );
|
||||
return ;
|
||||
}
|
||||
for ( int i = 0; i < 256; i++){
|
||||
uint16_t data;
|
||||
asm volatile ("inw %1, %0" : "=a"(data): "Nd"(DEVICE_CHANNEL));
|
||||
// printf (" %x ", data);
|
||||
|
||||
buffer[i] = data;
|
||||
}
|
||||
|
||||
//Then loop back to waiting for the next IRQ (or poll again -- see next note) for each successive sector.
|
||||
|
||||
}
|
||||
|
||||
void ATA_DEVICE::Identify(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 !
|
||||
|
||||
/*
|
||||
@ -106,88 +185,16 @@ void ATA_DEVICE::Identify(uint16_t DEVICE_CHANNEL,DEVICE_DRIVE drive ){
|
||||
|
||||
}
|
||||
|
||||
void ATA_DEVICE::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.
|
||||
|
||||
Notes: - When you send a command byte and the RDY bit of the Status Registers is clear, you may have to wait (technically up to 30 seconds) for the drive to spin up, before DRQ sets. You may also need to ignore ERR and DF the first four times that you read the Status, if you are polling.
|
||||
- for polling PIO drivers: After transferring the last uint16_t of a PIO data block to the data IO port, give the drive a 400ns delay to reset its DRQ bit (and possibly set BSY again, while emptying/filling its buffer to/from the drive).
|
||||
- on the "magic bits" sent to port 0x1f6: Bit 6 (value = 0x40) is the LBA bit. This must be set for either LBA28 or LBA48 transfers. It must be clear for CHS transfers. Bits 7 and 5 are obsolete for current ATA drives, but must be set for backwards compatibility with very old (ATA1) drives.
|
||||
|
||||
An example of a 28 bit LBA PIO mode read on the Primary bus:
|
||||
|
||||
*/
|
||||
|
||||
const int sectorCount = 1;
|
||||
|
||||
// Floating bus check
|
||||
uint8_t floatingBus = inb(DEVICE_CHANNEL | 7);
|
||||
if (floatingBus == 0xFF){
|
||||
printf("Floating bus!!");
|
||||
return ;
|
||||
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");
|
||||
}
|
||||
|
||||
//printf("Read LBA: 0x%x\n", LBA);
|
||||
// Send 0xE0 for the "master" or 0xF0 for the "slave", ORed with the highest 4 bits of the LBA to port 0x1F6: outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F))
|
||||
outb(DEVICE_CHANNEL | 6 , ( 0xE0 | (LBA >>28) ) );
|
||||
// Send a NULL byte to port 0x1F1, if you like (it is ignored and wastes lots of CPU time): outb(0x1F1, 0x00)
|
||||
outb(DEVICE_CHANNEL | 1, 0x0000 );
|
||||
//Send the sectorcount to port 0x1F2: outb(0x1F2, (unsigned char) count)
|
||||
outb(DEVICE_CHANNEL | 2, sectorCount);
|
||||
//Send the low 8 bits of the LBA to port 0x1F3: outb(0x1F3, (unsigned char) LBA))
|
||||
outb(DEVICE_CHANNEL | 3, LBA);
|
||||
//Send the next 8 bits of the LBA to port 0x1F4: outb(0x1F4, (unsigned char)(LBA >> 8))
|
||||
outb(DEVICE_CHANNEL | 4, (LBA >> 8));
|
||||
//Send the next 8 bits of the LBA to port 0x1F5: outb(0x1F5, (unsigned char)(LBA >> 16))
|
||||
outb(DEVICE_CHANNEL | 5, (LBA >> 16));
|
||||
//Send the "READ SECTORS" command (0x20) to port 0x1F7: outb(0x1F7, 0x20)
|
||||
outb(DEVICE_CHANNEL | 7, 0x20);
|
||||
|
||||
volatile int i,j;
|
||||
for(i=0;i<2000;i++)
|
||||
for(j=0;j<25000;j++)
|
||||
asm("NOP");
|
||||
|
||||
//Wait for an IRQ or poll.
|
||||
uint8_t status = inb(DEVICE_CHANNEL | 7);
|
||||
if( status == 0x00){
|
||||
printf("No drive\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//printf("Status: %x\n", status);
|
||||
// Check if busy!
|
||||
while((status & 0x80) == 0x80){
|
||||
printf("Reading....\r");
|
||||
status = inb(DEVICE_CHANNEL | 7);
|
||||
}
|
||||
|
||||
|
||||
if ((status & 0x01) == 0x01){
|
||||
printf("Error occured during read!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//Transfer 256 16-bit values, a uint16_t at a time, into your buffer from I/O port 0x1F0.
|
||||
if( status & 0x01){
|
||||
printf("Error!\n");
|
||||
printf("Status: 0x%x\n", status);
|
||||
uint16_t error_register = inb(DEVICE_CHANNEL | 1);
|
||||
printf("Error register 0x%x\n",error_register );
|
||||
return ;
|
||||
}
|
||||
for ( int i = 0; i < 256; i++){
|
||||
uint16_t data;
|
||||
asm volatile ("inw %1, %0" : "=a"(data): "Nd"(DEVICE_CHANNEL));
|
||||
// printf (" %x ", data);
|
||||
|
||||
buffer[i] = data;
|
||||
}
|
||||
|
||||
//Then loop back to waiting for the next IRQ (or poll again -- see next note) for each successive sector.
|
||||
//outb(channels[DEVICE_CHANNEL].base + 7 , 0x0);
|
||||
|
||||
}
|
||||
|
||||
void ATA_DEVICE::Write(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive) {
|
||||
printf("Not implemented\n");
|
||||
}
|
||||
|
||||
|
38
kernel/storage/ata pio/ataDevice.h
Normal file
38
kernel/storage/ata pio/ataDevice.h
Normal 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 );
|
||||
};
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdint-gcc.h>
|
||||
#include "../../terminal/kterm.h"
|
||||
#include "sampleIDE.definitions.h"
|
||||
#include "ideCommands.h"
|
||||
@ -240,3 +240,19 @@ inline void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t
|
||||
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;
|
||||
}
|
41
kernel/storage/vfs/FileSystem.cpp
Normal file
41
kernel/storage/vfs/FileSystem.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
18
kernel/storage/vfs/FileSystem.h
Normal file
18
kernel/storage/vfs/FileSystem.h
Normal 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);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
5
kernel/storage/vfs/Inode.cpp
Normal file
5
kernel/storage/vfs/Inode.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by nigel on 21/02/23.
|
||||
//
|
||||
|
||||
#include "Inode.h"
|
24
kernel/storage/vfs/Inode.h
Normal file
24
kernel/storage/vfs/Inode.h
Normal 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;
|
||||
};
|
||||
|
||||
|
32
kernel/storage/vfs/StorageTypes.h
Normal file
32
kernel/storage/vfs/StorageTypes.h
Normal 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;
|
||||
|
54
kernel/storage/vfs/VFS.cpp
Normal file
54
kernel/storage/vfs/VFS.cpp
Normal 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
17
kernel/storage/vfs/VFS.h
Normal 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];
|
||||
|
||||
};
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "drivers/io/io.h"
|
||||
#include "io/io.h"
|
||||
#define CURRENT_YEAR 2021
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdint-gcc.h>
|
||||
|
||||
void init_timer (uint32_t frequency);
|
@ -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
12
run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
cd CoreLib
|
||||
make
|
||||
cd ../kernel
|
||||
make clean
|
||||
make
|
||||
cd ..
|
||||
|
||||
./scripts/update_harddrive.sh
|
||||
./scripts/run_qemu.sh
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user