KERNEL TIME BOYS
This commit is contained in:
parent
5c9227ca36
commit
4d55b05585
4
Makefile
4
Makefile
@ -18,9 +18,9 @@ $(BUILD_DIR)/main_floppy.img: bootloader kernel
|
|||||||
dd if=$(BUILD_DIR)/stage1.bin of=$(BUILD_DIR)/main_floppy.img conv=notrunc
|
dd if=$(BUILD_DIR)/stage1.bin of=$(BUILD_DIR)/main_floppy.img conv=notrunc
|
||||||
mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/stage2.bin "::stage2.bin"
|
mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/stage2.bin "::stage2.bin"
|
||||||
mmd -i $(BUILD_DIR)/main_floppy.img "::boot"
|
mmd -i $(BUILD_DIR)/main_floppy.img "::boot"
|
||||||
mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/kernel.bin "::boot/kernel.bin"
|
mcopy -i $(BUILD_DIR)/main_floppy.img $(BUILD_DIR)/kernel.bin "::kernel.bin" # move to boot dir
|
||||||
mmd -i $(BUILD_DIR)/main_floppy.img "::misc"
|
mmd -i $(BUILD_DIR)/main_floppy.img "::misc"
|
||||||
mcopy -i $(BUILD_DIR)/main_floppy.img test.txt "::misc/test.txt"
|
mcopy -i $(BUILD_DIR)/main_floppy.img test.txt "::test.txt" # move to misc dir
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bootloader
|
# Bootloader
|
||||||
|
|||||||
@ -11,7 +11,7 @@ toolchain_binutils: $(BINUTILS_SRC).tar.gz
|
|||||||
|
|
||||||
cd toolchain && tar -xf binutils-$(BINUTILS_VERSION).tar.gz
|
cd toolchain && tar -xf binutils-$(BINUTILS_VERSION).tar.gz
|
||||||
mkdir -p $(BINUTILS_BUILD)
|
mkdir -p $(BINUTILS_BUILD)
|
||||||
cd $(BINUTILS_BUILD) && ../binutils-$(BINUTILS_VERSION)/configure \
|
cd $(BINUTILS_BUILD) && CFLAGS = ASM = ASMFLAGS = CC = CXX = LD = LINKFLAGS = LIBS = ../binutils-$(BINUTILS_VERSION)/configure \
|
||||||
--prefix="$(TOOLCHAIN_PREFIX)" \
|
--prefix="$(TOOLCHAIN_PREFIX)" \
|
||||||
--target=$(TARGET) \
|
--target=$(TARGET) \
|
||||||
--with-sysroot \
|
--with-sysroot \
|
||||||
@ -31,7 +31,7 @@ GCC_BUILD = toolchain/gcc-build-$(GCC_VERSION)
|
|||||||
toolchain_gcc: toolchain_binutils $(GCC_SRC).tar.gz
|
toolchain_gcc: toolchain_binutils $(GCC_SRC).tar.gz
|
||||||
cd toolchain && tar -xf gcc-$(GCC_VERSION).tar.gz
|
cd toolchain && tar -xf gcc-$(GCC_VERSION).tar.gz
|
||||||
mkdir -p $(GCC_BUILD)
|
mkdir -p $(GCC_BUILD)
|
||||||
cd $(GCC_BUILD) && ../gcc-$(GCC_VERSION)/configure \
|
cd $(GCC_BUILD) && CFLAGS = ASM = ASMFLAGS = CC = CXX = LD = LINKFLAGS = LIBS = ../gcc-$(GCC_VERSION)/configure \
|
||||||
--prefix="$(TOOLCHAIN_PREFIX)" \
|
--prefix="$(TOOLCHAIN_PREFIX)" \
|
||||||
--target=$(TARGET) \
|
--target=$(TARGET) \
|
||||||
--disable-nls \
|
--disable-nls \
|
||||||
|
|||||||
@ -3,7 +3,6 @@ TARGET_CFLAGS += -ffreestanding -nostdlib
|
|||||||
TARGET_LIBS += -lgcc
|
TARGET_LIBS += -lgcc
|
||||||
TARGET_LINKFLAGS += -T linker.ld -nostdlib
|
TARGET_LINKFLAGS += -T linker.ld -nostdlib
|
||||||
|
|
||||||
|
|
||||||
SOURCES_C=$(wildcard *.c)
|
SOURCES_C=$(wildcard *.c)
|
||||||
SOURCES_ASM=$(wildcard *.asm)
|
SOURCES_ASM=$(wildcard *.asm)
|
||||||
OBJECTS_C=$(patsubst %.c, $(BUILD_DIR)/stage2/c/%.obj, $(SOURCES_C))
|
OBJECTS_C=$(patsubst %.c, $(BUILD_DIR)/stage2/c/%.obj, $(SOURCES_C))
|
||||||
|
|||||||
@ -9,8 +9,8 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
#include "minmax.h"
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include "minmax.h"
|
||||||
|
|
||||||
#define SECTOR_SIZE 512
|
#define SECTOR_SIZE 512
|
||||||
#define MAX_PATH_SIZE 256
|
#define MAX_PATH_SIZE 256
|
||||||
@ -76,8 +76,10 @@ static FAT_Data* g_Data;
|
|||||||
static uint8_t* g_Fat = NULL;
|
static uint8_t* g_Fat = NULL;
|
||||||
static uint32_t g_DataSectionLba;
|
static uint32_t g_DataSectionLba;
|
||||||
|
|
||||||
bool FAT_ReadBootSector(DISK* disk) {
|
|
||||||
return DISK_ReadSectors(disk, 0, 1, &g_Data->BS.BootSectorBytes);
|
bool FAT_ReadBootSector(DISK* disk)
|
||||||
|
{
|
||||||
|
return DISK_ReadSectors(disk, 0, 1, g_Data->BS.BootSectorBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FAT_ReadFat(DISK* disk)
|
bool FAT_ReadFat(DISK* disk)
|
||||||
@ -85,29 +87,33 @@ bool FAT_ReadFat(DISK* disk)
|
|||||||
return DISK_ReadSectors(disk, g_Data->BS.BootSector.ReservedSectors, g_Data->BS.BootSector.SectorsPerFat, g_Fat);
|
return DISK_ReadSectors(disk, g_Data->BS.BootSector.ReservedSectors, g_Data->BS.BootSector.SectorsPerFat, g_Fat);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FAT_Initialize(DISK* disk) {
|
bool FAT_Initialize(DISK* disk)
|
||||||
|
{
|
||||||
g_Data = (FAT_Data*)MEMORY_FAT_ADDR;
|
g_Data = (FAT_Data*)MEMORY_FAT_ADDR;
|
||||||
|
|
||||||
// read bootsector
|
// read boot sector
|
||||||
if (!FAT_ReadBootSector(disk)) {
|
if (!FAT_ReadBootSector(disk))
|
||||||
printf("FAT: Bootsector Read Failed!\r\n");
|
{
|
||||||
|
printf("FAT: read boot sector failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read FAT
|
// read FAT
|
||||||
g_Fat = (uint8_t*)(g_Data + sizeof(FAT_Data));
|
g_Fat = (uint8_t*)g_Data + sizeof(FAT_Data);
|
||||||
uint32_t fatSize = g_Data->BS.BootSector.BytesPerSector * g_Data->BS.BootSector.SectorsPerFat;
|
uint32_t fatSize = g_Data->BS.BootSector.BytesPerSector * g_Data->BS.BootSector.SectorsPerFat;
|
||||||
if(sizeof(FAT_Data) + fatSize >= MEMORY_FAT_SIZE) {
|
if (sizeof(FAT_Data) + fatSize >= MEMORY_FAT_SIZE)
|
||||||
printf("FAT: Not Enough Memory to Read FAT!\r\nNeeded %u, Only Have %u\r\n", sizeof(FAT_Data) + fatSize, MEMORY_FAT_SIZE);
|
{
|
||||||
|
printf("FAT: not enough memory to read FAT! Required %lu, only have %u\r\n", sizeof(FAT_Data) + fatSize, MEMORY_FAT_SIZE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FAT_ReadFat(disk)) {
|
if (!FAT_ReadFat(disk))
|
||||||
printf("FAT: Failed to Read FAT!\r\n");
|
{
|
||||||
|
printf("FAT: read FAT failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// open root dir
|
// open root directory file
|
||||||
uint32_t rootDirLba = g_Data->BS.BootSector.ReservedSectors + g_Data->BS.BootSector.SectorsPerFat * g_Data->BS.BootSector.FatCount;
|
uint32_t rootDirLba = g_Data->BS.BootSector.ReservedSectors + g_Data->BS.BootSector.SectorsPerFat * g_Data->BS.BootSector.FatCount;
|
||||||
uint32_t rootDirSize = sizeof(FAT_DirectoryEntry) * g_Data->BS.BootSector.DirEntryCount;
|
uint32_t rootDirSize = sizeof(FAT_DirectoryEntry) * g_Data->BS.BootSector.DirEntryCount;
|
||||||
|
|
||||||
@ -117,14 +123,16 @@ bool FAT_Initialize(DISK* disk) {
|
|||||||
g_Data->RootDirectory.Public.Size = sizeof(FAT_DirectoryEntry) * g_Data->BS.BootSector.DirEntryCount;
|
g_Data->RootDirectory.Public.Size = sizeof(FAT_DirectoryEntry) * g_Data->BS.BootSector.DirEntryCount;
|
||||||
g_Data->RootDirectory.Opened = true;
|
g_Data->RootDirectory.Opened = true;
|
||||||
g_Data->RootDirectory.FirstCluster = rootDirLba;
|
g_Data->RootDirectory.FirstCluster = rootDirLba;
|
||||||
g_Data->RootDirectory.CurrentCluster = 0;
|
g_Data->RootDirectory.CurrentCluster = rootDirLba;
|
||||||
g_Data->RootDirectory.CurrentSectorInCluster = 0;
|
g_Data->RootDirectory.CurrentSectorInCluster = 0;
|
||||||
|
|
||||||
if (!DISK_ReadSectors(disk, rootDirLba, 1, g_Data->RootDirectory.Buffer)) {
|
if (!DISK_ReadSectors(disk, rootDirLba, 1, g_Data->RootDirectory.Buffer))
|
||||||
printf("FAT: Failed to Read Root Directory!\r\n");
|
{
|
||||||
|
printf("FAT: read root directory failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//calculate data
|
|
||||||
|
// calculate data section
|
||||||
uint32_t rootDirSectors = (rootDirSize + g_Data->BS.BootSector.BytesPerSector - 1) / g_Data->BS.BootSector.BytesPerSector;
|
uint32_t rootDirSectors = (rootDirSize + g_Data->BS.BootSector.BytesPerSector - 1) / g_Data->BS.BootSector.BytesPerSector;
|
||||||
g_DataSectionLba = rootDirLba + rootDirSectors;
|
g_DataSectionLba = rootDirLba + rootDirSectors;
|
||||||
|
|
||||||
@ -135,20 +143,25 @@ bool FAT_Initialize(DISK* disk) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FAT_ClusterToLba(uint32_t cluster) {
|
uint32_t FAT_ClusterToLba(uint32_t cluster)
|
||||||
|
{
|
||||||
return g_DataSectionLba + (cluster - 2) * g_Data->BS.BootSector.SectorsPerCluster;
|
return g_DataSectionLba + (cluster - 2) * g_Data->BS.BootSector.SectorsPerCluster;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAT_File* FAT_OpenEntry(DISK* disk, FAT_DirectoryEntry* entry) {
|
FAT_File* FAT_OpenEntry(DISK* disk, FAT_DirectoryEntry* entry)
|
||||||
|
{
|
||||||
// find empty handle
|
// find empty handle
|
||||||
int handle = -1;
|
int handle = -1;
|
||||||
for (int i = 0; i < MAX_FILE_HANDLES && handle < 0; i++) {
|
for (int i = 0; i < MAX_FILE_HANDLES && handle < 0; i++)
|
||||||
|
{
|
||||||
if (!g_Data->OpenedFiles[i].Opened)
|
if (!g_Data->OpenedFiles[i].Opened)
|
||||||
handle = i;
|
handle = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// out of handles
|
// out of handles
|
||||||
if (handle < 0) {
|
if (handle < 0)
|
||||||
printf("FAT: Out of File Handles!\r\n");
|
{
|
||||||
|
printf("FAT: out of file handles\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +175,9 @@ FAT_File* FAT_OpenEntry(DISK* disk, FAT_DirectoryEntry* entry) {
|
|||||||
fd->CurrentCluster = fd->FirstCluster;
|
fd->CurrentCluster = fd->FirstCluster;
|
||||||
fd->CurrentSectorInCluster = 0;
|
fd->CurrentSectorInCluster = 0;
|
||||||
|
|
||||||
if (!DISK_ReadSectors(disk, FAT_ClusterToLba(fd->CurrentCluster), 1, fd->Buffer)) {
|
if (!DISK_ReadSectors(disk, FAT_ClusterToLba(fd->CurrentCluster), 1, fd->Buffer))
|
||||||
printf("FAT: Failed to Open Entry, Read Error!\nCluster Is: %u\n", fd->CurrentCluster);
|
{
|
||||||
|
printf("FAT: open entry failed - read error cluster=%u lba=%u\n", fd->CurrentCluster, FAT_ClusterToLba(fd->CurrentCluster));
|
||||||
for (int i = 0; i < 11; i++)
|
for (int i = 0; i < 11; i++)
|
||||||
printf("%c", entry->Name[i]);
|
printf("%c", entry->Name[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -174,16 +188,18 @@ FAT_File* FAT_OpenEntry(DISK* disk, FAT_DirectoryEntry* entry) {
|
|||||||
return &fd->Public;
|
return &fd->Public;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FAT_NextCluster(uint32_t currentCluster) {
|
uint32_t FAT_NextCluster(uint32_t currentCluster)
|
||||||
|
{
|
||||||
uint32_t fatIndex = currentCluster * 3 / 2;
|
uint32_t fatIndex = currentCluster * 3 / 2;
|
||||||
|
|
||||||
if (currentCluster % 2 == 0)
|
if (currentCluster % 2 == 0)
|
||||||
return (*(uint16_t*)(g_Fat + fatIndex)) & 0x0FFF;
|
return (*(uint16_t*)(g_Fat + fatIndex)) & 0x0FFF;
|
||||||
else
|
else
|
||||||
return (*(uint16_t*)(g_Fat + fatIndex)) >> 4;
|
return (*(uint16_t*)(g_Fat + fatIndex)) >> 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FAT_Read(DISK* disk, FAT_File* file, uint32_t byteCount, void* dataOut) {
|
uint32_t FAT_Read(DISK* disk, FAT_File* file, uint32_t byteCount, void* dataOut)
|
||||||
|
{
|
||||||
// get file data
|
// get file data
|
||||||
FAT_FileData* fd = (file->Handle == ROOT_DIRECTORY_HANDLE)
|
FAT_FileData* fd = (file->Handle == ROOT_DIRECTORY_HANDLE)
|
||||||
? &g_Data->RootDirectory
|
? &g_Data->RootDirectory
|
||||||
@ -191,46 +207,56 @@ uint32_t FAT_Read(DISK* disk, FAT_File* file, uint32_t byteCount, void* dataOut)
|
|||||||
|
|
||||||
uint8_t* u8DataOut = (uint8_t*)dataOut;
|
uint8_t* u8DataOut = (uint8_t*)dataOut;
|
||||||
|
|
||||||
// don't read past EOF
|
// don't read past the end of the file
|
||||||
if (!fd->Public.IsDirectory || (fd->Public.IsDirectory && fd->Public.Size != 0))
|
if (!fd->Public.IsDirectory || (fd->Public.IsDirectory && fd->Public.Size != 0))
|
||||||
byteCount = min(byteCount, fd->Public.Size - fd->Public.Position);
|
byteCount = min(byteCount, fd->Public.Size - fd->Public.Position);
|
||||||
|
|
||||||
while (byteCount > 0) {
|
while (byteCount > 0)
|
||||||
|
{
|
||||||
uint32_t leftInBuffer = SECTOR_SIZE - (fd->Public.Position % SECTOR_SIZE);
|
uint32_t leftInBuffer = SECTOR_SIZE - (fd->Public.Position % SECTOR_SIZE);
|
||||||
uint32_t take = min(byteCount, leftInBuffer);
|
uint32_t take = min(byteCount, leftInBuffer);
|
||||||
|
|
||||||
memcpy(u8DataOut, fd->Buffer + fd->Public.Position % SECTOR_SIZE, take);
|
memcpy(u8DataOut, fd->Buffer + fd->Public.Position % SECTOR_SIZE, take);
|
||||||
u8DataOut += take;
|
u8DataOut += take;
|
||||||
fd->Public.Position += take;
|
fd->Public.Position += take;
|
||||||
byteCount -= take;
|
byteCount -= take;
|
||||||
|
|
||||||
// see if we need to read more data
|
// printf("leftInBuffer=%lu take=%lu\r\n", leftInBuffer, take);
|
||||||
if (leftInBuffer == take) {
|
// See if we need to read more data
|
||||||
// root dir handler
|
if (leftInBuffer == take)
|
||||||
if (fd->Public.Handle == ROOT_DIRECTORY_HANDLE) {
|
{
|
||||||
|
// Special handling for root directory
|
||||||
|
if (fd->Public.Handle == ROOT_DIRECTORY_HANDLE)
|
||||||
|
{
|
||||||
++fd->CurrentCluster;
|
++fd->CurrentCluster;
|
||||||
// read next sect.
|
|
||||||
if (!DISK_ReadSectors(disk, fd->CurrentCluster, 1, fd->Buffer)) {
|
// read next sector
|
||||||
printf("FAT: Read Error!\r\n");
|
if (!DISK_ReadSectors(disk, fd->CurrentCluster, 1, fd->Buffer))
|
||||||
|
{
|
||||||
|
printf("FAT: read error!\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
// read next sect.
|
{
|
||||||
if (++fd->CurrentSectorInCluster >= g_Data->BS.BootSector.SectorsPerCluster) {
|
// calculate next cluster & sector to read
|
||||||
// calc next cluster & sect. to read
|
if (++fd->CurrentSectorInCluster >= g_Data->BS.BootSector.SectorsPerCluster)
|
||||||
|
{
|
||||||
fd->CurrentSectorInCluster = 0;
|
fd->CurrentSectorInCluster = 0;
|
||||||
fd->CurrentCluster = FAT_NextCluster(fd->CurrentCluster);
|
fd->CurrentCluster = FAT_NextCluster(fd->CurrentCluster);
|
||||||
}
|
}
|
||||||
if (fd->CurrentCluster >= 0x0FF8) {
|
|
||||||
// mark EOF
|
if (fd->CurrentCluster >= 0xFF8)
|
||||||
|
{
|
||||||
|
// Mark end of file
|
||||||
fd->Public.Size = fd->Public.Position;
|
fd->Public.Size = fd->Public.Position;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read next sect.
|
// read next sector
|
||||||
if (!DISK_ReadSectors(disk, FAT_ClusterToLba(fd->CurrentCluster) + fd->CurrentSectorInCluster, 1, fd->Buffer)) {
|
if (!DISK_ReadSectors(disk, FAT_ClusterToLba(fd->CurrentCluster) + fd->CurrentSectorInCluster, 1, fd->Buffer))
|
||||||
printf("FAT: Read Error!\r\n");
|
{
|
||||||
|
printf("FAT: read error!\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,44 +265,51 @@ uint32_t FAT_Read(DISK* disk, FAT_File* file, uint32_t byteCount, void* dataOut)
|
|||||||
|
|
||||||
return u8DataOut - (uint8_t*)dataOut;
|
return u8DataOut - (uint8_t*)dataOut;
|
||||||
}
|
}
|
||||||
bool FAT_ReadEntry(DISK* disk, FAT_File* file, FAT_DirectoryEntry* dirEntry) {
|
|
||||||
return FAT_Read(disk, file, sizeof(FAT_DirectoryEntry), dirEntry) == sizeof(FAT_DirectoryEntry);
|
|
||||||
|
|
||||||
|
bool FAT_ReadEntry(DISK* disk, FAT_File* file, FAT_DirectoryEntry* dirEntry)
|
||||||
|
{
|
||||||
|
return FAT_Read(disk, file, sizeof(FAT_DirectoryEntry), dirEntry) == sizeof(FAT_DirectoryEntry);
|
||||||
}
|
}
|
||||||
void FAT_Close(FAT_File* file) {
|
|
||||||
if (file->Handle == ROOT_DIRECTORY_HANDLE) {
|
void FAT_Close(FAT_File* file)
|
||||||
|
{
|
||||||
|
if (file->Handle == ROOT_DIRECTORY_HANDLE)
|
||||||
|
{
|
||||||
file->Position = 0;
|
file->Position = 0;
|
||||||
g_Data->RootDirectory.CurrentCluster = g_Data->RootDirectory.FirstCluster;
|
g_Data->RootDirectory.CurrentCluster = g_Data->RootDirectory.FirstCluster;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
g_Data->OpenedFiles[file->Handle].Opened = false;
|
g_Data->OpenedFiles[file->Handle].Opened = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FAT_FindFile(DISK* disk, FAT_File* file, const char* name, FAT_DirectoryEntry* entryOut) {
|
bool FAT_FindFile(DISK* disk, FAT_File* file, const char* name, FAT_DirectoryEntry* entryOut)
|
||||||
char fatName[11];
|
{
|
||||||
|
char fatName[12];
|
||||||
FAT_DirectoryEntry entry;
|
FAT_DirectoryEntry entry;
|
||||||
|
|
||||||
// convert from name to fat name
|
// convert from name to fat name
|
||||||
memset(fatName, ' ', sizeof(fatName));
|
memset(fatName, ' ', sizeof(fatName));
|
||||||
fatName[11] + '\0';
|
fatName[11] = '\0';
|
||||||
|
|
||||||
const char* ext = strchr(name, '.');
|
const char* ext = strchr(name, '.');
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
ext = name + 11;
|
ext = name + 11;
|
||||||
|
|
||||||
for (int i = 0; i < 8 && name[i] && name + i < ext; i++)
|
for (int i = 0; i < 8 && name[i] && name + i < ext; i++)
|
||||||
fatName[i] = toupper(name[i]);
|
fatName[i] = toupper(name[i]);
|
||||||
if (ext != name + 11) {
|
|
||||||
|
if (ext != name + 11)
|
||||||
|
{
|
||||||
for (int i = 0; i < 3 && ext[i + 1]; i++)
|
for (int i = 0; i < 3 && ext[i + 1]; i++)
|
||||||
fatName[i + 8] = toupper(ext[i + 1]);
|
fatName[i + 8] = toupper(ext[i + 1]);
|
||||||
}
|
}
|
||||||
while (FAT_ReadEntry(disk, file, &entry)) {
|
|
||||||
// for (int i = 0; i < 11; i++)
|
|
||||||
// printf("%c", fatName);
|
|
||||||
|
|
||||||
// for (int i = 0; i < 11; i++)
|
while (FAT_ReadEntry(disk, file, &entry))
|
||||||
// printf("%c", entry.Name[i]);
|
{
|
||||||
if (memcmp(fatName, entry.Name, 11) == 0) {
|
if (memcmp(fatName, entry.Name, 11) == 0)
|
||||||
|
{
|
||||||
*entryOut = entry;
|
*entryOut = entry;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -285,7 +318,8 @@ bool FAT_FindFile(DISK* disk, FAT_File* file, const char* name, FAT_DirectoryEnt
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAT_File* FAT_Open(DISK* disk, const char* path) {
|
FAT_File* FAT_Open(DISK* disk, const char* path)
|
||||||
|
{
|
||||||
char name[MAX_PATH_SIZE];
|
char name[MAX_PATH_SIZE];
|
||||||
|
|
||||||
// ignore leading slash
|
// ignore leading slash
|
||||||
@ -298,38 +332,44 @@ FAT_File* FAT_Open(DISK* disk, const char* path) {
|
|||||||
// extract next file name from path
|
// extract next file name from path
|
||||||
bool isLast = false;
|
bool isLast = false;
|
||||||
const char* delim = strchr(path, '/');
|
const char* delim = strchr(path, '/');
|
||||||
if (delim != NULL) {
|
if (delim != NULL)
|
||||||
|
{
|
||||||
memcpy(name, path, delim - path);
|
memcpy(name, path, delim - path);
|
||||||
name[delim - path + 1] = '\0';
|
name[delim - path + 1] = '\0';
|
||||||
path = delim + 1;
|
path = delim + 1;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
unsigned len = strlen(path);
|
unsigned len = strlen(path);
|
||||||
memcpy(name, path, len);
|
memcpy(name, path, len);
|
||||||
name[len + 1] = '\0';
|
name[len + 1] = '\0';
|
||||||
path += len;
|
path += len;
|
||||||
bool isLast = true;
|
isLast = true;
|
||||||
}
|
}
|
||||||
// find directory entry in current dir
|
|
||||||
|
// find directory entry in current directory
|
||||||
FAT_DirectoryEntry entry;
|
FAT_DirectoryEntry entry;
|
||||||
if (FAT_FindFile(disk, current, name, &entry)) {
|
if (FAT_FindFile(disk, current, name, &entry))
|
||||||
|
{
|
||||||
FAT_Close(current);
|
FAT_Close(current);
|
||||||
|
|
||||||
// check if DIR
|
// check if directory
|
||||||
if (!isLast && entry.Attributes & FAT_ATTRIBUTE_DIRECTORY == 0) {
|
if (!isLast && entry.Attributes & FAT_ATTRIBUTE_DIRECTORY == 0)
|
||||||
printf("FAT: %s is NOT a Directory!\r\n", name);
|
{
|
||||||
|
printf("FAT: %s not a directory\r\n", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// open new DIR entry
|
// open new directory entry
|
||||||
current = FAT_OpenEntry(disk, &entry);
|
current = FAT_OpenEntry(disk, &entry);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
FAT_Close(current);
|
FAT_Close(current);
|
||||||
printf("FAT: %s NOT Found!", name);
|
|
||||||
|
printf("FAT: %s not found\r\n", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
|||||||
@ -8,10 +8,18 @@
|
|||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
|
#include "memdefs.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n"
|
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n"
|
||||||
#define VERSION "v0.0.1"
|
#define VERSION "v0.0.1"
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t* KernelLoadBuffer = (uint8_t*)MEMORY_LOAD_KERNEL;
|
||||||
|
uint8_t* Kernel = (uint8_t*)MEMORY_KERNEL_ADDR;
|
||||||
|
|
||||||
|
typedef void (*KernelStart)();
|
||||||
|
|
||||||
void* g_data = (void*)0x20000;
|
void* g_data = (void*)0x20000;
|
||||||
|
|
||||||
void puts_realmode(const char* str) {
|
void puts_realmode(const char* str) {
|
||||||
@ -57,36 +65,43 @@ void* g_data = (void*)0x20000;
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
printf("Done!\n");
|
printf("Done!\n");
|
||||||
// printf("Listing Root DIR...\n");
|
|
||||||
// // browse files in root
|
|
||||||
FAT_File* fd = FAT_Open(&disk, "/");
|
|
||||||
FAT_DirectoryEntry entry;
|
|
||||||
int i = 0;
|
|
||||||
// while (FAT_ReadEntry(&disk, fd, &entry) && i++ < 5) {
|
|
||||||
// printf(" ");
|
|
||||||
// for (int i = 0; i < 11; i++)
|
|
||||||
// putc(entry.Name[i]);
|
|
||||||
// printf("\n");
|
|
||||||
// }
|
|
||||||
// FAT_Close(fd);
|
|
||||||
|
|
||||||
|
// test fat driver
|
||||||
printf("Testing FAT Driver...");
|
printf("Testing FAT Driver...");
|
||||||
// read test.txt
|
// read test.txt
|
||||||
|
FAT_File* ft = FAT_Open(&disk, "/");
|
||||||
char buffer[100];
|
char buffer[100];
|
||||||
uint32_t read;
|
uint32_t testread;
|
||||||
fd = FAT_Open(&disk, "misc/test.txt");
|
ft = FAT_Open(&disk, "test.txt"); // move test.txt in MISC folder later (TM)
|
||||||
while ((read = FAT_Read(&disk, fd, sizeof(buffer), buffer)))
|
while ((testread = FAT_Read(&disk, ft, sizeof(buffer), buffer)))
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < read; i++)
|
for (uint32_t i = 0; i < testread; i++)
|
||||||
{
|
{
|
||||||
if (buffer[i] == '\n')
|
if (buffer[i] == '\n')
|
||||||
putc('\r');
|
putc('\r');
|
||||||
putc(buffer[i]);
|
putc(buffer[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FAT_Close(ft);
|
||||||
|
|
||||||
|
// load kernel from disk
|
||||||
|
printf("Loading Kernel...");
|
||||||
|
FAT_File* fd = FAT_Open(&disk, "/kernel.bin"); // move to /boot later????? (TM)
|
||||||
|
uint32_t read;
|
||||||
|
uint8_t* kernelBuffer = Kernel;
|
||||||
|
while ((read = FAT_Read(&disk, fd, MEMORY_LOAD_SIZE, KernelLoadBuffer)))
|
||||||
|
{
|
||||||
|
memcpy(kernelBuffer, KernelLoadBuffer, read);
|
||||||
|
kernelBuffer += read;
|
||||||
|
}
|
||||||
FAT_Close(fd);
|
FAT_Close(fd);
|
||||||
|
|
||||||
printf("Loading Kernel...");
|
// execute kernel
|
||||||
|
KernelStart kernelStart = (KernelStart)Kernel;
|
||||||
|
kernelStart();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
for (;;);
|
for (;;);
|
||||||
|
|||||||
@ -15,6 +15,9 @@
|
|||||||
#define MEMORY_FAT_ADDR ((void*)0x20000)
|
#define MEMORY_FAT_ADDR ((void*)0x20000)
|
||||||
#define MEMORY_FAT_SIZE 0x00010000
|
#define MEMORY_FAT_SIZE 0x00010000
|
||||||
|
|
||||||
|
#define MEMORY_LOAD_KERNEL ((void*)0x30000)
|
||||||
|
#define MEMORY_LOAD_SIZE 0x00010000
|
||||||
|
|
||||||
// 0x00020000 - 0x00030000 - stage2
|
// 0x00020000 - 0x00030000 - stage2
|
||||||
|
|
||||||
// 0x00030000 - 0x00080000 - free
|
// 0x00030000 - 0x00080000 - free
|
||||||
@ -22,3 +25,5 @@
|
|||||||
// 0x00080000 - 0x0009FFFF - Extended BIOS data area
|
// 0x00080000 - 0x0009FFFF - Extended BIOS data area
|
||||||
// 0x000A0000 - 0x000C7FFF - Video
|
// 0x000A0000 - 0x000C7FFF - Video
|
||||||
// 0x000C8000 - 0x000FFFFF - BIOS
|
// 0x000C8000 - 0x000FFFFF - BIOS
|
||||||
|
|
||||||
|
#define MEMORY_KERNEL_ADDR ((void*)0x100000)
|
||||||
@ -293,6 +293,7 @@ void printf(const char* fmt, ...) {
|
|||||||
length = PRINTF_LENGTH_DEFAULT;
|
length = PRINTF_LENGTH_DEFAULT;
|
||||||
radix = 10;
|
radix = 10;
|
||||||
sign = false;
|
sign = false;
|
||||||
|
bool number = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
TARGET_ASMFLAGS += -f elf
|
TARGET_ASMFLAGS += -f elf
|
||||||
TARGET_CFLAGS += -ffreestanding -nostdlib
|
TARGET_CFLAGS += -ffreestanding -nostdlib -I.
|
||||||
TARGET_LIBS += -lgcc
|
TARGET_LIBS += -lgcc
|
||||||
TARGET_LINKFLAGS += -T linker.ld -nostdlib
|
TARGET_LINKFLAGS += -T linker.ld -nostdlib
|
||||||
|
|
||||||
|
SOURCES_C=$(shell find . -type f -name "*.c")
|
||||||
SOURCES_C=$(wildcard *.c)
|
SOURCES_ASM=$(shell find . -type f -name "*.asm")
|
||||||
SOURCES_ASM=$(wildcard *.asm)
|
|
||||||
OBJECTS_C=$(patsubst %.c, $(BUILD_DIR)/kernel/c/%.obj, $(SOURCES_C))
|
OBJECTS_C=$(patsubst %.c, $(BUILD_DIR)/kernel/c/%.obj, $(SOURCES_C))
|
||||||
OBJECTS_ASM=$(patsubst %.asm, $(BUILD_DIR)/kernel/asm/%.obj, $(SOURCES_ASM))
|
OBJECTS_ASM=$(patsubst %.asm, $(BUILD_DIR)/kernel/asm/%.obj, $(SOURCES_ASM))
|
||||||
|
|
||||||
@ -16,17 +15,18 @@ all: kernel
|
|||||||
kernel: $(BUILD_DIR)/kernel.bin
|
kernel: $(BUILD_DIR)/kernel.bin
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel.bin: $(OBJECTS_ASM) $(OBJECTS_C)
|
$(BUILD_DIR)/kernel.bin: $(OBJECTS_ASM) $(OBJECTS_C)
|
||||||
$(TARGET_LD) $(TARGET_LINKFLAGS) -Wl,-Map=$(BUILD_DIR)/kernel.map -o $@ $^ $(TARGET_LIBS)
|
@$(TARGET_LD) $(TARGET_LINKFLAGS) -Wl,-Map=$(BUILD_DIR)/kernel.map -o $@ $^ $(TARGET_LIBS)
|
||||||
|
@echo "--> Created: kernel.bin"
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel/c/%.obj: %.c always
|
$(BUILD_DIR)/kernel/c/%.obj: %.c
|
||||||
$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
|
@mkdir -p $(@D)
|
||||||
|
@$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
|
||||||
|
@echo "--> Compiled: " $<
|
||||||
|
|
||||||
$(BUILD_DIR)/kernel/asm/%.obj: %.asm always
|
$(BUILD_DIR)/kernel/asm/%.obj: %.asm
|
||||||
$(TARGET_ASM) $(TARGET_ASMFLAGS) -o $@ $<
|
@mkdir -p $(@D)
|
||||||
|
@$(TARGET_ASM) $(TARGET_ASMFLAGS) -o $@ $<
|
||||||
always:
|
@echo "--> Compiled: " $<
|
||||||
mkdir -p $(BUILD_DIR)/kernel/c
|
|
||||||
mkdir -p $(BUILD_DIR)/kernel/asm
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(BUILD_DIR)/kernel.bin
|
rm -f $(BUILD_DIR)/kernel.bin
|
||||||
21
src/kernel/arch/i686/io.asm
Normal file
21
src/kernel/arch/i686/io.asm
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
;/////////////////////;
|
||||||
|
;Nanite OS ;
|
||||||
|
;COPYRIGHT (C) 2024 ;
|
||||||
|
;Tyler McGurrin ;
|
||||||
|
;/////////////////////;
|
||||||
|
|
||||||
|
global x86_outb
|
||||||
|
x86_outb:
|
||||||
|
[bits 32]
|
||||||
|
mov dx, [esp + 4]
|
||||||
|
mov al, [esp + 8]
|
||||||
|
out dx, al
|
||||||
|
ret
|
||||||
|
|
||||||
|
global x86_inb
|
||||||
|
x86_inb:
|
||||||
|
[bits 32]
|
||||||
|
mov dx, [esp + 4]
|
||||||
|
xor eax, eax
|
||||||
|
in al, dx
|
||||||
|
ret
|
||||||
11
src/kernel/arch/i686/io.h
Normal file
11
src/kernel/arch/i686/io.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/*----------------*\
|
||||||
|
|Nanite OS |
|
||||||
|
|Copyright (C) 2024|
|
||||||
|
|Tyler McGurrin |
|
||||||
|
\*----------------*/
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void __attribute__((cdecl)) x86_outb(uint16_t port, uint8_t value);
|
||||||
|
uint8_t __attribute__((cdecl)) x86_inb(uint16_t port);
|
||||||
@ -1,8 +1,9 @@
|
|||||||
ENTRY(entry)
|
ENTRY(start)
|
||||||
OUTPUT_FORMAT("binary")
|
OUTPUT_FORMAT("binary")
|
||||||
phys = 0x000100000;
|
phys = 0x00100000;
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS
|
||||||
|
{
|
||||||
. = phys;
|
. = phys;
|
||||||
|
|
||||||
.entry : { __entry_start = .; *(.entry) }
|
.entry : { __entry_start = .; *(.entry) }
|
||||||
|
|||||||
@ -4,25 +4,20 @@
|
|||||||
|Tyler McGurrin |
|
|Tyler McGurrin |
|
||||||
\*----------------*/
|
\*----------------*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "x86.h"
|
#include <memory.h"
|
||||||
#include "disk.h"
|
|
||||||
#include "fat.h"
|
|
||||||
|
|
||||||
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n"
|
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/ \n"
|
||||||
#define VERSION "v0.0.1"
|
#define VERSION "v0.0.1"
|
||||||
|
|
||||||
void* g_data = (void*)0x20000;
|
extern uint8_t __bss_start;
|
||||||
|
extern uint8_t __end;
|
||||||
|
|
||||||
void puts_realmode(const char* str) {
|
void __attribute__((section(".entry"))) start(uint16_t bootDrive) {
|
||||||
while (*str) {
|
clrscr();
|
||||||
x86_realmode_putc(*str);
|
printf("%s", LOGO);
|
||||||
++str;
|
printf("The Nano OS %s\n-------------------------------------\n", VERSION);
|
||||||
}
|
printf("Kernel Loaded!");
|
||||||
}
|
|
||||||
|
|
||||||
void __attribute__((cdecl)) start(uint16_t bootDrive) {
|
|
||||||
printf("Done!\n"); // done msg for load kernel (LEAVE HERE)
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
for (;;);
|
for (;;);
|
||||||
|
|||||||
36
src/kernel/memory.c
Normal file
36
src/kernel/memory.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*----------------*\
|
||||||
|
|Nanite OS |
|
||||||
|
|Copyright (C) 2024|
|
||||||
|
|Tyler McGurrin |
|
||||||
|
\*----------------*/
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
void* memcpy(void* dst, const void* src, uint16_t num) {
|
||||||
|
uint8_t* u8Dst = (uint8_t *)dst;
|
||||||
|
const uint8_t* u8Src = (const uint8_t *)src;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < num; i++)
|
||||||
|
u8Dst[i] = u8Src[i];
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset (void * ptr, int value, uint16_t num) {
|
||||||
|
uint8_t* u8Ptr = (uint8_t *)ptr;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < num; i++)
|
||||||
|
u8Ptr[i] = (uint8_t)value;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void* ptr1, const void * ptr2, uint16_t num) {
|
||||||
|
const uint8_t* u8Ptr1 = (const uint8_t *)ptr1;
|
||||||
|
const uint8_t* u8Ptr2 = (const uint8_t *)ptr2;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < num; i++)
|
||||||
|
if (u8Ptr1[i] != u8Ptr2[i])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
11
src/kernel/memory.h
Normal file
11
src/kernel/memory.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/*----------------*\
|
||||||
|
|Nanite OS |
|
||||||
|
|Copyright (C) 2024|
|
||||||
|
|Tyler McGurrin |
|
||||||
|
\*----------------*/
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void* memcpy(void* dst, const void* src, uint16_t num);
|
||||||
|
void* memset(void* ptr, int value, uint16_t num);
|
||||||
|
int memcmp(const void* ptr1, const void * ptr2, uint16_t num);
|
||||||
@ -3,8 +3,8 @@
|
|||||||
|Copyright (C) 2024|
|
|Copyright (C) 2024|
|
||||||
|Tyler McGurrin |
|
|Tyler McGurrin |
|
||||||
\*----------------*/
|
\*----------------*/
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "x86.h"
|
#include <arch/i686/io.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@ -293,6 +293,8 @@ void printf(const char* fmt, ...) {
|
|||||||
length = PRINTF_LENGTH_DEFAULT;
|
length = PRINTF_LENGTH_DEFAULT;
|
||||||
radix = 10;
|
radix = 10;
|
||||||
sign = false;
|
sign = false;
|
||||||
|
bool number = false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,3 +11,4 @@ void putc(char c);
|
|||||||
void puts(const char* str);
|
void puts(const char* str);
|
||||||
void printf(const char* fmt, ...);
|
void printf(const char* fmt, ...);
|
||||||
void print_buffer(const char* msg, const void* buffer, uint32_t count);
|
void print_buffer(const char* msg, const void* buffer, uint32_t count);
|
||||||
|
void setcursor(int x, int y);
|
||||||
Loading…
x
Reference in New Issue
Block a user