Added file reading via filehandlers. Added support for directories. Processes are now created using filehandlers.
This commit is contained in:
parent
2bbc81955d
commit
2f2a7a3e45
6
Makefile
6
Makefile
@ -2,7 +2,7 @@ CFLAGS = -g -std=gnu11 -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exce
|
|||||||
CXXFLAGS = -g -m32 -fno-use-cxa-atexit -mgeneral-regs-only -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -fpermissive -fno-pie -fno-stack-protector -I.
|
CXXFLAGS = -g -m32 -fno-use-cxa-atexit -mgeneral-regs-only -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -fpermissive -fno-pie -fno-stack-protector -I.
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
DISK_IMG_FILES = build/kernel/kernel.bin build/world/world.bin hello.txt alpha.txt \
|
DISK_IMG_FILES = build/kernel/kernel.bin hello.txt alpha.txt \
|
||||||
build/hello/hello.bin
|
build/hello/hello.bin
|
||||||
|
|
||||||
KERNEL_CPP_SRCS = $(wildcard src/kernel/*.cpp) $(wildcard src/kernel/*/*.cpp)
|
KERNEL_CPP_SRCS = $(wildcard src/kernel/*.cpp) $(wildcard src/kernel/*/*.cpp)
|
||||||
@ -39,12 +39,14 @@ run: disk.img
|
|||||||
debug: disk.img
|
debug: disk.img
|
||||||
qemu-system-i386 -s -S -no-reboot -no-shutdown disk.img & gdb --command=gdbscript
|
qemu-system-i386 -s -S -no-reboot -no-shutdown disk.img & gdb --command=gdbscript
|
||||||
|
|
||||||
disk.img: clean prepare build/boot/boot.bin build/boot_stage2/boot.bin $(DISK_IMG_FILES)
|
disk.img: clean prepare build/boot/boot.bin build/boot_stage2/boot.bin $(DISK_IMG_FILES) build/world/world.bin
|
||||||
dd if=/dev/zero of=disk.img count=43 bs=100k
|
dd if=/dev/zero of=disk.img count=43 bs=100k
|
||||||
dd if=build/boot/boot.bin of=disk.img conv=notrunc
|
dd if=build/boot/boot.bin of=disk.img conv=notrunc
|
||||||
dd obs=512 seek=1 if=build/boot_stage2/boot.bin of=disk.img conv=notrunc
|
dd obs=512 seek=1 if=build/boot_stage2/boot.bin of=disk.img conv=notrunc
|
||||||
mount disk.img img.d
|
mount disk.img img.d
|
||||||
|
mkdir img.d/etc/
|
||||||
cp $(DISK_IMG_FILES) img.d/
|
cp $(DISK_IMG_FILES) img.d/
|
||||||
|
cp build/world/world.bin img.d/etc/world.bin
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
umount img.d
|
umount img.d
|
||||||
chmod 777 disk.img
|
chmod 777 disk.img
|
||||||
|
@ -28,8 +28,8 @@ int write(uint32_t count, void* filehanlder, uint8_t* buffer) {
|
|||||||
asm volatile ("mov $11, %%eax; mov %0, %%ebx; mov %1, %%esi; mov %2, %%edi; int $0x7f" : : "m" (count), "m" (filehanlder), "m" (buffer): "ebx", "esi", "edi");
|
asm volatile ("mov $11, %%eax; mov %0, %%ebx; mov %1, %%esi; mov %2, %%edi; int $0x7f" : : "m" (count), "m" (filehanlder), "m" (buffer): "ebx", "esi", "edi");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fork(char* filename) {
|
uint32_t fork(uint32_t fh) {
|
||||||
asm volatile("mov $7, %%eax; mov %0, %%esi; int $0x7f" : : "m" (filename) : "esi");
|
asm volatile("mov $7, %%eax; mov %0, %%esi; int $0x7f" : : "m" (fh) : "esi");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bindStdout(uint32_t PID) {
|
uint32_t bindStdout(uint32_t PID) {
|
||||||
@ -40,6 +40,14 @@ uint32_t bindStdin(uint32_t PID) {
|
|||||||
asm volatile("mov $14, %%eax; mov %0, %%esi; int $0x7f" : : "m" (PID) : "esi");
|
asm volatile("mov $14, %%eax; mov %0, %%esi; int $0x7f" : : "m" (PID) : "esi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fopen(char* filename) {
|
||||||
|
asm volatile("mov $15, %%eax; mov %0, %%esi; int $0x7f" : : "m" (filename) : "esi");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fclose(uint32_t fh) {
|
||||||
|
asm volatile("mov $16, %%eax; mov %0, %%esi; int $0x7f" : : "m" (fh) : "esi");
|
||||||
|
}
|
||||||
|
|
||||||
void bindToKeyboard() {
|
void bindToKeyboard() {
|
||||||
asm volatile ("mov $12, %%eax; int $0x7f" : : :);
|
asm volatile ("mov $12, %%eax; int $0x7f" : : :);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ void* localalloc(uint32_t size);
|
|||||||
void localdelete(void* ptr);
|
void localdelete(void* ptr);
|
||||||
uint32_t filesize(char* filename);
|
uint32_t filesize(char* filename);
|
||||||
|
|
||||||
uint32_t fork(char* filename);
|
uint32_t fork(uint32_t fh);
|
||||||
uint32_t bindStdout(uint32_t PID);
|
uint32_t bindStdout(uint32_t PID);
|
||||||
uint32_t bindStdin(uint32_t PID);
|
uint32_t bindStdin(uint32_t PID);
|
||||||
|
|
||||||
@ -19,6 +19,9 @@ int read(uint32_t count, void* filehandler, uint8_t* buffer);
|
|||||||
int write(uint32_t count, void* filehandler, uint8_t* buffer);
|
int write(uint32_t count, void* filehandler, uint8_t* buffer);
|
||||||
void bindToKeyboard();
|
void bindToKeyboard();
|
||||||
|
|
||||||
|
int fopen(char* filename);
|
||||||
|
void fclose(uint32_t fh);
|
||||||
|
|
||||||
int int_to_decimal(unsigned int number, char* string_buffer);
|
int int_to_decimal(unsigned int number, char* string_buffer);
|
||||||
int int_to_hex(unsigned int number, char* string_buffer);
|
int int_to_hex(unsigned int number, char* string_buffer);
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
uint16_t identify_result[256];
|
uint16_t identify_result[256];
|
||||||
uint32_t total_28_lbas = 0;
|
uint32_t total_28_lbas = 0;
|
||||||
|
|
||||||
uint8_t* rootDirEntries;
|
DirectoryEntry* rootDirEntries;
|
||||||
uint16_t* FAT1;
|
uint16_t* FAT1;
|
||||||
|
|
||||||
uint16_t countReserved;
|
uint16_t countReserved;
|
||||||
@ -21,7 +21,7 @@ uint16_t sectorsPerFAT;
|
|||||||
|
|
||||||
|
|
||||||
void init_atapio() {
|
void init_atapio() {
|
||||||
rootDirEntries = new uint8_t[8192];
|
rootDirEntries = (DirectoryEntry*)new uint8_t[8192];
|
||||||
FAT1 = (uint16_t*)(new uint8_t[512 * 34]);
|
FAT1 = (uint16_t*)(new uint8_t[512 * 34]);
|
||||||
|
|
||||||
uint32_t boot_sector = new uint32_t[1024];
|
uint32_t boot_sector = new uint32_t[1024];
|
||||||
@ -65,7 +65,7 @@ void init_atapio() {
|
|||||||
total_28_lbas = *(uint32_t*)(identify_result+60);
|
total_28_lbas = *(uint32_t*)(identify_result+60);
|
||||||
|
|
||||||
// We've initialised now, let's load the FAT and RootDirEntries.
|
// We've initialised now, let's load the FAT and RootDirEntries.
|
||||||
read_sectors(sectorsPerFAT * countFATs + countReserved, countRDEs / 16, rootDirEntries);
|
read_sectors(sectorsPerFAT * countFATs + countReserved, countRDEs / 16, (uint8_t*)rootDirEntries);
|
||||||
read_sectors(countReserved, sectorsPerFAT, (uint8_t*)FAT1);
|
read_sectors(countReserved, sectorsPerFAT, (uint8_t*)FAT1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,27 +97,46 @@ void read_sectors(uint32_t address, int count, uint8_t* buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t file_exists(char* filename) {
|
uint32_t clusterToSector(uint32_t cluster) {
|
||||||
for (int i=0; i<countRDEs; i++) {
|
return cluster + (sectorsPerFAT * countFATs) + (countRDEs / 16) + (countReserved - 1) - 1;
|
||||||
bool found = strcmp(rootDirEntries+(i*32), filename, 11);
|
|
||||||
if (found) {
|
|
||||||
uint16_t* correctEntry = (uint16_t*)(rootDirEntries+(i*32));
|
|
||||||
return correctEntry[13];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_file(char* filename, uint8_t* destination) {
|
int split_on_char(char c, char* str, char** split) {
|
||||||
uint16_t location = file_exists(filename);
|
char* cstr = str;
|
||||||
if (!location)
|
char* last = str;
|
||||||
return;
|
uint32_t count = 0;
|
||||||
|
while (*cstr) {
|
||||||
|
if (*cstr == c) {
|
||||||
|
*cstr = 0;
|
||||||
|
split[count++] = last;
|
||||||
|
last = cstr+1;
|
||||||
|
}
|
||||||
|
cstr++;
|
||||||
|
}
|
||||||
|
split[count++] = last;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void to83(char* filename, char* buf83) {
|
||||||
|
char* c = filename;
|
||||||
|
for (int i=0;i<11;i++)
|
||||||
|
buf83[i] = ' ';
|
||||||
|
uint32_t bufpos = 0;
|
||||||
|
while (*c && bufpos != 11) {
|
||||||
|
if (*c == '.')
|
||||||
|
bufpos = 8;
|
||||||
|
else
|
||||||
|
buf83[bufpos++] = *c & 223;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_file(uint32_t location, uint8_t* destination) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
while (!loaded) {
|
while (!loaded) {
|
||||||
uint16_t fromSector = location + (sectorsPerFAT * countFATs) + (countRDEs / 16) + (countReserved - 1) - 1;
|
uint16_t fromSector = clusterToSector(location);
|
||||||
read_sector(fromSector, destination+offset);
|
read_sector(fromSector, destination+offset);
|
||||||
offset += 512;
|
offset += 512;
|
||||||
|
|
||||||
@ -127,13 +146,110 @@ void load_file(char* filename, uint8_t* destination) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t file_size(char* filename) {
|
int calc_size(uint32_t location) {
|
||||||
for (int i=0; i<countRDEs; i++) {
|
int offset = 0;
|
||||||
bool found = strcmp(rootDirEntries+(i*32), filename, 11);
|
|
||||||
|
bool loaded = false;
|
||||||
|
while (!loaded) {
|
||||||
|
uint16_t fromSector = clusterToSector(location);
|
||||||
|
offset += 512;
|
||||||
|
|
||||||
|
location = FAT1[location++];
|
||||||
|
if (location == 0xffff)
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectoryEntry* get_DE(char* filename) {
|
||||||
|
DirectoryEntry* dirbuf;
|
||||||
|
Directory dir = {
|
||||||
|
.entry = rootDirEntries,
|
||||||
|
.entries = countRDEs
|
||||||
|
};
|
||||||
|
|
||||||
|
char* levels[8];
|
||||||
|
int count = split_on_char('/', filename, levels);
|
||||||
|
|
||||||
|
for (int i=0; i<(count-1); i++) {
|
||||||
|
char normalname[11] = {' '};
|
||||||
|
to83(levels[i], normalname);
|
||||||
|
for (int e=0; e<dir.entries; e++) {
|
||||||
|
bool found=strcmp(dir.entry[e].name, normalname, 11);
|
||||||
|
if (found) {
|
||||||
|
DirectoryEntry* de = &dir.entry[e];
|
||||||
|
uint32_t size = calc_size(de->firstClusterLow);
|
||||||
|
dirbuf = (DirectoryEntry*)(new uint8_t[size]);
|
||||||
|
uint32_t cluster = de->firstClusterLow;
|
||||||
|
load_file(cluster, (uint8_t*)dirbuf);
|
||||||
|
dir.entry = dirbuf;
|
||||||
|
dir.entries = size / 32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char normalname[11];
|
||||||
|
to83(levels[count-1], normalname);
|
||||||
|
|
||||||
|
for (int i=0; i<dir.entries; i++) {
|
||||||
|
bool found = strcmp(dir.entry[i].name, normalname, 11);
|
||||||
if (found) {
|
if (found) {
|
||||||
uint32_t* correctEntry = (uint32_t*)(rootDirEntries+(i*32));
|
return &dir.entry[i];
|
||||||
return correctEntry[7];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t file_exists(char* filename) {
|
||||||
|
DirectoryEntry* de = get_DE(filename);
|
||||||
|
if (de)
|
||||||
|
return de->firstClusterLow;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t file_size(char* filename) {
|
||||||
|
for (int i=0; i<countRDEs; i++) {
|
||||||
|
bool found = strcmp(rootDirEntries[i].name, filename, 11);
|
||||||
|
if (found) {
|
||||||
|
if (rootDirEntries[i].size % 512)
|
||||||
|
return ((rootDirEntries[i].size / 512) + 1) * 512;
|
||||||
|
else
|
||||||
|
return rootDirEntries[i].size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_file(char* filename, uint8_t* location) {
|
||||||
|
DirectoryEntry* de = get_DE(filename);
|
||||||
|
load_file(de->firstClusterLow, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
FATFileReadWriter::FATFileReadWriter(uint32_t owner, char* filename)
|
||||||
|
: ReadWriter(owner) {
|
||||||
|
this->bytesRead = 0;
|
||||||
|
DirectoryEntry* de = get_DE(filename);
|
||||||
|
this->sizeBytes = de->size;
|
||||||
|
this->currentCluster = de->firstClusterLow;
|
||||||
|
this->read_buffer = new uint8_t[512];
|
||||||
|
read_sector(clusterToSector(this->currentCluster), this->read_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t FATFileReadWriter::read(uint32_t count, uint8_t* buffer) {
|
||||||
|
int index = 0;
|
||||||
|
while (count) {
|
||||||
|
buffer[index] = this->read_buffer[this->bytesRead++];
|
||||||
|
if (this->bytesRead == 512) {
|
||||||
|
this->currentCluster = FAT1[this->currentCluster++];
|
||||||
|
read_sector(clusterToSector(this->currentCluster), this->read_buffer);
|
||||||
|
this->bytesRead = 0;
|
||||||
|
}
|
||||||
|
count--;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t FATFileReadWriter::write(uint32_t count, uint8_t* buffer) {}
|
||||||
|
uint32_t FATFileReadWriter::size() {
|
||||||
|
return this->sizeBytes;
|
||||||
|
}
|
||||||
|
@ -9,6 +9,49 @@
|
|||||||
#include "allocate.h"
|
#include "allocate.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
#include "stdio/readwriter.h"
|
||||||
|
|
||||||
|
struct __attribute__((packed)) DirectoryEntry {
|
||||||
|
char name[11];
|
||||||
|
uint8_t _ignored0 : 3;
|
||||||
|
uint8_t archive : 1;
|
||||||
|
uint8_t directory : 1;
|
||||||
|
uint8_t volumeid : 1;
|
||||||
|
uint8_t system : 1;
|
||||||
|
uint8_t hidden : 1;
|
||||||
|
uint8_t readonly : 1;
|
||||||
|
uint8_t _ignored1;
|
||||||
|
uint16_t createdHour : 5;
|
||||||
|
uint16_t createdMinute : 6;
|
||||||
|
uint16_t createdSecond : 5;
|
||||||
|
|
||||||
|
uint16_t createdYear : 7;
|
||||||
|
uint16_t createdMonth : 4;
|
||||||
|
uint16_t createdDay : 5;
|
||||||
|
|
||||||
|
uint16_t lastAccessYear : 7;
|
||||||
|
uint16_t lastAccessMonth : 4;
|
||||||
|
uint16_t lastAccessDay : 5;
|
||||||
|
|
||||||
|
uint16_t firstClusterHigh;
|
||||||
|
|
||||||
|
uint16_t modifiedHour : 5;
|
||||||
|
uint16_t modifiedMinute : 6;
|
||||||
|
uint16_t modifiedSecond : 5;
|
||||||
|
|
||||||
|
uint16_t modifiedYear : 7;
|
||||||
|
uint16_t modifiedMonth : 4;
|
||||||
|
uint16_t modifiedDay : 5;
|
||||||
|
|
||||||
|
uint16_t firstClusterLow;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Directory {
|
||||||
|
DirectoryEntry* entry;
|
||||||
|
uint32_t entries;
|
||||||
|
};
|
||||||
|
|
||||||
void init_atapio();
|
void init_atapio();
|
||||||
void read_sector(uint32_t address, uint8_t* buffer);
|
void read_sector(uint32_t address, uint8_t* buffer);
|
||||||
void read_sectors(uint32_t address, int count, uint8_t* buffer);
|
void read_sectors(uint32_t address, int count, uint8_t* buffer);
|
||||||
@ -17,4 +60,18 @@ void load_file(char* filename, uint8_t* location);
|
|||||||
|
|
||||||
uint32_t file_size(char* filename);
|
uint32_t file_size(char* filename);
|
||||||
|
|
||||||
|
class FATFileReadWriter : public ReadWriter {
|
||||||
|
private:
|
||||||
|
uint32_t sizeBytes;
|
||||||
|
uint32_t bytesRead;
|
||||||
|
uint32_t currentCluster;
|
||||||
|
uint8_t* read_buffer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FATFileReadWriter(uint32_t owner, char* filename);
|
||||||
|
uint32_t read(uint32_t count, uint8_t* buffer) override;
|
||||||
|
uint32_t write(uint32_t count, uint8_t* buffer) override;
|
||||||
|
uint32_t size() override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -55,7 +55,7 @@ namespace xnoe {
|
|||||||
return xnoe::Maybe<value>();
|
return xnoe::Maybe<value>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(key k, value v) {
|
void remove(key k) {
|
||||||
xnoe::linkedlist<xnoe::tuple<key, value>>* list = &table[xnoe::hash<key>(k) % 4096];
|
xnoe::linkedlist<xnoe::tuple<key, value>>* list = &table[xnoe::hash<key>(k) % 4096];
|
||||||
xnoe::linkedlistelem<xnoe::tuple<key, value>>* current = list->start;
|
xnoe::linkedlistelem<xnoe::tuple<key, value>>* current = list->start;
|
||||||
if (current) {
|
if (current) {
|
||||||
|
@ -6,6 +6,7 @@ namespace Global {
|
|||||||
Process* currentProc = 0;
|
Process* currentProc = 0;
|
||||||
tss_struct* tss = 0;
|
tss_struct* tss = 0;
|
||||||
bool currentProcValid = false;
|
bool currentProcValid = false;
|
||||||
|
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size) {
|
void* operator new (uint32_t size) {
|
||||||
|
@ -7,6 +7,11 @@ class Kernel;
|
|||||||
class Allocator;
|
class Allocator;
|
||||||
class Process;
|
class Process;
|
||||||
struct tss_struct;
|
struct tss_struct;
|
||||||
|
class ReadWriter;
|
||||||
|
namespace xnoe {
|
||||||
|
template<class, class>
|
||||||
|
class hashtable;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Global {
|
namespace Global {
|
||||||
extern Allocator* allocator;
|
extern Allocator* allocator;
|
||||||
@ -14,6 +19,7 @@ namespace Global {
|
|||||||
extern Process* currentProc;
|
extern Process* currentProc;
|
||||||
extern tss_struct* tss;
|
extern tss_struct* tss;
|
||||||
extern bool currentProcValid;
|
extern bool currentProcValid;
|
||||||
|
extern xnoe::hashtable<void*, ReadWriter*>* FH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size);
|
void* operator new (uint32_t size);
|
||||||
|
@ -164,6 +164,9 @@ void syscall(frame_struct* frame) {
|
|||||||
// 13: bindStdout :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdout of another process.
|
// 13: bindStdout :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdout of another process.
|
||||||
// 14: bindStdin :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdin of another process.
|
// 14: bindStdin :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdin of another process.
|
||||||
|
|
||||||
|
// 15: fopen :: char* path esi -> int filehandler // Returns a filehandler to the file.
|
||||||
|
// 16: fclose :: int filehandler esi -> void // Closes a file handler.
|
||||||
|
|
||||||
// File handlers:
|
// File handlers:
|
||||||
// 0: Stdout
|
// 0: Stdout
|
||||||
// 1: Stdin
|
// 1: Stdin
|
||||||
@ -196,10 +199,7 @@ void syscall(frame_struct* frame) {
|
|||||||
break;
|
break;
|
||||||
case 7: {
|
case 7: {
|
||||||
asm("cli");
|
asm("cli");
|
||||||
char filename[12];
|
Process* p = Global::kernel->createProcess(esi);
|
||||||
for (int i=0; i<12; i++)
|
|
||||||
filename[i] = ((char*)(frame->esi))[i];
|
|
||||||
Process* p = Global::kernel->createProcess(filename);
|
|
||||||
rval = p->PID;
|
rval = p->PID;
|
||||||
asm("sti");
|
asm("sti");
|
||||||
break;
|
break;
|
||||||
@ -219,7 +219,7 @@ void syscall(frame_struct* frame) {
|
|||||||
|
|
||||||
rval = stdin->read(frame->ebx, edi);
|
rval = stdin->read(frame->ebx, edi);
|
||||||
} else {
|
} else {
|
||||||
xnoe::Maybe<ReadWriter*> fh = Global::kernel->FH->get(esi);
|
xnoe::Maybe<ReadWriter*> fh = Global::FH->get(esi);
|
||||||
if (!fh.is_ok()) {
|
if (!fh.is_ok()) {
|
||||||
rval = 0;
|
rval = 0;
|
||||||
break;
|
break;
|
||||||
@ -239,7 +239,7 @@ void syscall(frame_struct* frame) {
|
|||||||
|
|
||||||
rval = stdout->write(frame->ebx, edi);
|
rval = stdout->write(frame->ebx, edi);
|
||||||
} else {
|
} else {
|
||||||
xnoe::Maybe<ReadWriter*> fh = Global::kernel->FH->get(esi);
|
xnoe::Maybe<ReadWriter*> fh = Global::FH->get(esi);
|
||||||
if (!fh.is_ok()) {
|
if (!fh.is_ok()) {
|
||||||
rval = 0;
|
rval = 0;
|
||||||
break;
|
break;
|
||||||
@ -285,6 +285,19 @@ void syscall(frame_struct* frame) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 15: {
|
||||||
|
ReadWriter* file = new FATFileReadWriter(0, esi);
|
||||||
|
rval = Global::kernel->mapFH(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 16: {
|
||||||
|
xnoe::Maybe<ReadWriter*> f = Global::FH->get(esi);
|
||||||
|
if (f.is_ok()) {
|
||||||
|
delete f.get();
|
||||||
|
Global::kernel->unmapFH(esi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,12 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
|
|||||||
|
|
||||||
void Kernel::init_kernel() {
|
void Kernel::init_kernel() {
|
||||||
this->pid_map = new xnoe::hashtable<uint32_t, Process*>();
|
this->pid_map = new xnoe::hashtable<uint32_t, Process*>();
|
||||||
this->FH = new xnoe::hashtable<void*, ReadWriter*>();
|
Global::FH = new xnoe::hashtable<void*, ReadWriter*>();
|
||||||
this->globalISRStack = (new uint8_t[0x8000]) + 0x8000;
|
this->globalISRStack = (new uint8_t[0x8000]) + 0x8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* Kernel::createProcess(char* filename) {
|
Process* Kernel::createProcess(uint32_t fh) {
|
||||||
Process* p = new Process(currentPID, this->PD, 0xc0000000, filename);
|
Process* p = new Process(currentPID, this->PD, 0xc0000000, fh);
|
||||||
this->pid_map->set(currentPID, p);
|
this->pid_map->set(currentPID, p);
|
||||||
currentPID++;
|
currentPID++;
|
||||||
|
|
||||||
@ -32,23 +32,27 @@ Process* Kernel::createProcess(char* filename) {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* Kernel::createProcess(char* filename, ReadWriter* stdout) {
|
Process* Kernel::createProcess(uint32_t fh, ReadWriter* stdout) {
|
||||||
Process* p = this->createProcess(filename);
|
Process* p = this->createProcess(fh);
|
||||||
p->stdout = stdout;
|
p->stdout = stdout;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::destroyProcess(Process* p) {
|
void Kernel::destroyProcess(Process* p) {
|
||||||
this->processes.remove(p);
|
this->processes.remove(p);
|
||||||
this->pid_map->remove(p->PID, p);
|
this->pid_map->remove(p->PID);
|
||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Kernel::mapFH(ReadWriter* fh) {
|
int Kernel::mapFH(ReadWriter* fh) {
|
||||||
this->FH->set(this->lastFH++, fh);
|
Global::FH->set(this->lastFH++, fh);
|
||||||
return this->lastFH - 1;
|
return this->lastFH - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Kernel::unmapFH(uint32_t fh) {
|
||||||
|
Global::FH->remove((void*)fh);
|
||||||
|
}
|
||||||
|
|
||||||
//void Kernel::loadPrimaryStack() {
|
//void Kernel::loadPrimaryStack() {
|
||||||
// asm volatile("mov %0, %%esp"::"m"(this->stack - 64));
|
// asm volatile("mov %0, %%esp"::"m"(this->stack - 64));
|
||||||
//}
|
//}
|
@ -16,7 +16,6 @@ public:
|
|||||||
Terminal* terminal;
|
Terminal* terminal;
|
||||||
|
|
||||||
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
||||||
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
|
||||||
|
|
||||||
xnoe::linkedlist<Process*> processes;
|
xnoe::linkedlist<Process*> processes;
|
||||||
xnoe::linkedlist<Process*> KBListeners;
|
xnoe::linkedlist<Process*> KBListeners;
|
||||||
@ -25,11 +24,12 @@ public:
|
|||||||
|
|
||||||
void init_kernel();
|
void init_kernel();
|
||||||
|
|
||||||
Process* createProcess(char* filename);
|
Process* createProcess(uint32_t fh);
|
||||||
Process* createProcess(char* filename, ReadWriter* stdout);
|
Process* createProcess(uint32_t fh, ReadWriter* stdout);
|
||||||
void destroyProcess(Process* p);
|
void destroyProcess(Process* p);
|
||||||
|
|
||||||
int mapFH(ReadWriter* fh);
|
int mapFH(ReadWriter* fh);
|
||||||
|
void unmapFH(uint32_t fh);
|
||||||
//void loadPrimaryStack();
|
//void loadPrimaryStack();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,7 +44,10 @@ int main() {
|
|||||||
|
|
||||||
term->printf("KERNEL OK!\n");
|
term->printf("KERNEL OK!\n");
|
||||||
|
|
||||||
Process* p1 = kernel.createProcess("WORLD BIN", term);
|
ReadWriter* worldbin = new FATFileReadWriter(0, "etc/world.bin");
|
||||||
|
uint32_t fh = kernel.mapFH(worldbin);
|
||||||
|
|
||||||
|
Process* p1 = kernel.createProcess(fh, term);
|
||||||
|
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ Process::Process(uint32_t PID)
|
|||||||
this->kernelStackPtr = (new uint8_t[0x1000]) + 0x1000;
|
this->kernelStackPtr = (new uint8_t[0x1000]) + 0x1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename)
|
Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh)
|
||||||
: Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) {
|
: Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) {
|
||||||
this->stdout = 0;
|
this->stdout = 0;
|
||||||
this->stdin = 0;
|
this->stdin = 0;
|
||||||
@ -47,45 +47,51 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha
|
|||||||
for (int index = inheritBase >> 22; index < 1024; index++)
|
for (int index = inheritBase >> 22; index < 1024; index++)
|
||||||
this->PD->page_directory[index] = inherit->page_directory[index];
|
this->PD->page_directory[index] = inherit->page_directory[index];
|
||||||
|
|
||||||
uint8_t* program_data = this->allocate(file_size(filename) + 12) + 12;
|
xnoe::Maybe<ReadWriter*> file = Global::FH->get(fh);
|
||||||
|
if (file.is_ok()) {
|
||||||
|
ReadWriter* filereader = file.get();
|
||||||
|
uint32_t filesize = filereader->size();
|
||||||
|
uint8_t* program_data = this->allocate(filesize + 12) + 12;
|
||||||
|
|
||||||
this->stack = this->allocate(0x8000);
|
this->stack = this->allocate(0x8000);
|
||||||
this->kernelStackPtr = (new uint8_t[0x1000]) + 0xffc;
|
this->kernelStackPtr = (new uint8_t[0x1000]) + 0xffc;
|
||||||
this->kernelStackPtrDefault = this->kernelStackPtr;
|
this->kernelStackPtrDefault = this->kernelStackPtr;
|
||||||
|
|
||||||
uint32_t pCR3;
|
uint32_t pCR3;
|
||||||
asm ("mov %%cr3, %0" : "=a" (pCR3) :);
|
asm ("mov %%cr3, %0" : "=a" (pCR3) :);
|
||||||
this->PD->select();
|
this->PD->select();
|
||||||
|
|
||||||
// We also need to initialise ESP and the stack
|
// We also need to initialise ESP and the stack
|
||||||
uint32_t* stack32 = ((uint32_t)this->kernelStackPtr);
|
uint32_t* stack32 = ((uint32_t)this->kernelStackPtr);
|
||||||
*(--stack32) = 0x23; // SS
|
*(--stack32) = 0x23; // SS
|
||||||
*(--stack32) = ((uint32_t)this->stack + 0x8000); // ESP
|
*(--stack32) = ((uint32_t)this->stack + 0x8000); // ESP
|
||||||
*(--stack32) = 0x200; // EFLAGS
|
*(--stack32) = 0x200; // EFLAGS
|
||||||
*(--stack32) = 27; // CS
|
*(--stack32) = 27; // CS
|
||||||
*(--stack32) = (uint32_t)program_data; // EIP
|
*(--stack32) = (uint32_t)program_data; // EIP
|
||||||
*(--stack32) = ((uint32_t)this->stack + 0x8000); // EBP
|
*(--stack32) = ((uint32_t)this->stack + 0x8000); // EBP
|
||||||
|
|
||||||
uint32_t rEBP = stack32;
|
uint32_t rEBP = stack32;
|
||||||
|
|
||||||
//stack32--;
|
//stack32--;
|
||||||
*(--stack32) = 0; // EAX
|
*(--stack32) = 0; // EAX
|
||||||
*(--stack32) = 0; // ECX
|
*(--stack32) = 0; // ECX
|
||||||
*(--stack32) = 0; // EDX
|
*(--stack32) = 0; // EDX
|
||||||
*(--stack32) = 0; // EBX
|
*(--stack32) = 0; // EBX
|
||||||
*(--stack32) = 0; // ESP
|
*(--stack32) = 0; // ESP
|
||||||
*(--stack32) = rEBP; // EBP
|
*(--stack32) = rEBP; // EBP
|
||||||
*(--stack32) = 0; // ESI
|
*(--stack32) = 0; // ESI
|
||||||
*(--stack32) = 0; // EDI
|
*(--stack32) = 0; // EDI
|
||||||
stack32--;
|
stack32--;
|
||||||
*(--stack32) = &catchall_return; // cachall_return
|
*(--stack32) = &catchall_return; // cachall_return
|
||||||
stack32--;
|
stack32--;
|
||||||
|
|
||||||
this->kernelStackPtr = stack32;
|
this->kernelStackPtr = stack32;
|
||||||
|
|
||||||
load_file(filename, program_data);
|
//load_file(filename, program_data);
|
||||||
|
filereader->read(filesize, program_data);
|
||||||
|
|
||||||
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::~Process() {
|
Process::~Process() {
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
|
|
||||||
Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
||||||
Process(uint32_t PID);
|
Process(uint32_t PID);
|
||||||
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename);
|
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uint32_t fh);
|
||||||
|
|
||||||
~Process(); // Iterate through allocations and free those; delete stack
|
~Process(); // Iterate through allocations and free those; delete stack
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ CircularRWBuffer::CircularRWBuffer(uint32_t reader, uint32_t writer)
|
|||||||
this->writePtr = 0;
|
this->writePtr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CircularRWBuffer::write(uint32_t count, uint8_t* buffer) {
|
uint32_t CircularRWBuffer::write(uint32_t count, uint8_t* buffer) {
|
||||||
int i=0;
|
int i=0;
|
||||||
while (i < count) {
|
while (i < count) {
|
||||||
this->buffer[this->writePtr] = buffer[i];
|
this->buffer[this->writePtr] = buffer[i];
|
||||||
@ -24,7 +24,7 @@ int CircularRWBuffer::write(uint32_t count, uint8_t* buffer) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CircularRWBuffer::read(uint32_t count, uint8_t* buffer) {
|
uint32_t CircularRWBuffer::read(uint32_t count, uint8_t* buffer) {
|
||||||
int i=0;
|
int i=0;
|
||||||
while (i < count) {
|
while (i < count) {
|
||||||
if (this->readPtr == this->writePtr)
|
if (this->readPtr == this->writePtr)
|
||||||
@ -38,3 +38,7 @@ int CircularRWBuffer::read(uint32_t count, uint8_t* buffer) {
|
|||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t CircularRWBuffer::size() {
|
||||||
|
return 0;
|
||||||
|
}
|
@ -12,8 +12,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
CircularRWBuffer(uint32_t reader, uint32_t writer);
|
CircularRWBuffer(uint32_t reader, uint32_t writer);
|
||||||
|
|
||||||
int read(uint32_t count, uint8_t* buffer) override;
|
uint32_t read(uint32_t count, uint8_t* buffer) override;
|
||||||
int write(uint32_t count, uint8_t* buffer) override;
|
uint32_t write(uint32_t count, uint8_t* buffer) override;
|
||||||
|
uint32_t size() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -12,8 +12,9 @@ void ReadWriter::giveWritePerm(uint32_t PID) {
|
|||||||
this->allowedWrite.append(PID);
|
this->allowedWrite.append(PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReadWriter::read(uint32_t count, uint8_t* buffer){}
|
uint32_t ReadWriter::read(uint32_t count, uint8_t* buffer){}
|
||||||
int ReadWriter::write(uint32_t count, uint8_t* buffer){}
|
uint32_t ReadWriter::write(uint32_t count, uint8_t* buffer){}
|
||||||
|
uint32_t ReadWriter::size(){}
|
||||||
|
|
||||||
bool ReadWriter::canRead(uint32_t PID) {
|
bool ReadWriter::canRead(uint32_t PID) {
|
||||||
if (this->owner == PID)
|
if (this->owner == PID)
|
||||||
|
@ -15,8 +15,9 @@ public:
|
|||||||
void giveReadPerm(uint32_t PID);
|
void giveReadPerm(uint32_t PID);
|
||||||
void giveWritePerm(uint32_t PID);
|
void giveWritePerm(uint32_t PID);
|
||||||
|
|
||||||
virtual int read(uint32_t count, uint8_t* buffer);
|
virtual uint32_t read(uint32_t count, uint8_t* buffer);
|
||||||
virtual int write(uint32_t count, uint8_t* buffer);
|
virtual uint32_t write(uint32_t count, uint8_t* buffer);
|
||||||
|
virtual uint32_t size();
|
||||||
uint32_t getOwner();
|
uint32_t getOwner();
|
||||||
bool canRead(uint32_t PID);
|
bool canRead(uint32_t PID);
|
||||||
bool canWrite(uint32_t PID);
|
bool canWrite(uint32_t PID);
|
||||||
|
@ -182,7 +182,7 @@ void Terminal::printf(const char* string, ...) {
|
|||||||
va_end(ptr);
|
va_end(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Terminal::write(uint32_t count, uint8_t* string) {
|
uint32_t Terminal::write(uint32_t count, uint8_t* string) {
|
||||||
/*char* buf = new char[count+1];
|
/*char* buf = new char[count+1];
|
||||||
for (int i=0;i<count;i++) {
|
for (int i=0;i<count;i++) {
|
||||||
buf[i] = buffer[i];
|
buf[i] = buffer[i];
|
||||||
@ -272,7 +272,7 @@ int Terminal::write(uint32_t count, uint8_t* string) {
|
|||||||
this->set_curpos(this->cur_x, this->cur_y);
|
this->set_curpos(this->cur_x, this->cur_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Terminal::read(uint32_t count, uint8_t* buffer) {}
|
uint32_t Terminal::read(uint32_t count, uint8_t* buffer) {}
|
||||||
|
|
||||||
void Terminal::clear_screen() {
|
void Terminal::clear_screen() {
|
||||||
for (int i=0; i < width * height * pages; i++) {
|
for (int i=0; i < width * height * pages; i++) {
|
||||||
|
@ -38,8 +38,8 @@ public:
|
|||||||
|
|
||||||
void printf(const char* string, ...);
|
void printf(const char* string, ...);
|
||||||
|
|
||||||
int write(uint32_t count, uint8_t* buffer) override;
|
uint32_t write(uint32_t count, uint8_t* buffer) override;
|
||||||
int read(uint32_t count, uint8_t* buffer) override;
|
uint32_t read(uint32_t count, uint8_t* buffer) override;
|
||||||
|
|
||||||
void clear_screen();
|
void clear_screen();
|
||||||
void set_curpos(int x, int y);
|
void set_curpos(int x, int y);
|
||||||
|
@ -168,15 +168,16 @@ int main() {
|
|||||||
for (int i=0; i<80;i++)
|
for (int i=0; i<80;i++)
|
||||||
write(1, 0, &plus);
|
write(1, 0, &plus);
|
||||||
|
|
||||||
char* hello_bin = "HELLO BIN";
|
uint32_t program = fopen("hello.bin");
|
||||||
uint32_t p1 = fork(hello_bin);
|
uint32_t p1 = fork(program);
|
||||||
uint32_t p2 = fork(hello_bin);
|
|
||||||
|
|
||||||
uint32_t p1out = bindStdout(p1);
|
uint32_t p1out = bindStdout(p1);
|
||||||
uint32_t p1in = bindStdin(p1);
|
uint32_t p1in = bindStdin(p1);
|
||||||
|
fclose(program);
|
||||||
|
program = fopen("hello.bin");
|
||||||
|
uint32_t p2 = fork(program);
|
||||||
uint32_t p2out = bindStdout(p2);
|
uint32_t p2out = bindStdout(p2);
|
||||||
uint32_t p2in = bindStdin(p2);
|
uint32_t p2in = bindStdin(p2);
|
||||||
|
fclose(program);
|
||||||
|
|
||||||
procbuffer b1 = {
|
procbuffer b1 = {
|
||||||
.buffer = localalloc(21 * 38),
|
.buffer = localalloc(21 * 38),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user