mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
Implemented custom filesystem and got it to compile. It seems that it isn't loading the 3rd stage bootloader though
This commit is contained in:
+20
-11
@@ -4,28 +4,29 @@ Sector = 512 Bytes
|
|||||||
Block = 4096 Bytes
|
Block = 4096 Bytes
|
||||||
|
|
||||||
Reserved sectors:
|
Reserved sectors:
|
||||||
Sector 0 - Bootsector, will be loaded by the Bios into memory and executed (512B)
|
Sector 0..3 - Bootblock, will be loaded by the Bios into memory and executed (512B)
|
||||||
Sector 1..4 - Superblock, contains metadata about the filesystem itself (4KiB)
|
Sector 4..7 - Superblock, contains metadata about the filesystem itself (4KiB)
|
||||||
|
|
||||||
Superblock structure: (4096B)
|
Superblock structure: (4096B)
|
||||||
FS Name
|
Device ID
|
||||||
FS Size (Sector)
|
Max File Size
|
||||||
FS Size (Block)
|
|
||||||
INode Count
|
INode Count
|
||||||
INodes per sector
|
|
||||||
INode Bitmap Block
|
INode Bitmap Block
|
||||||
Data Bitmap Block
|
|
||||||
INodes Start
|
INodes Start
|
||||||
|
INode Block Count
|
||||||
|
INodes per sector
|
||||||
|
Data Bitmap Block
|
||||||
Data Start
|
Data Start
|
||||||
Root INode Number
|
Data Block Count
|
||||||
Extents per indirect
|
Root INode Pointer
|
||||||
|
First Unreserved INode
|
||||||
|
|
||||||
INode structure: (64B)
|
INode structure: (64B)
|
||||||
Type
|
Type
|
||||||
Size (bytes)
|
Size (bytes)
|
||||||
Block Count (size in blocks)
|
Sector Count (size in sectors)
|
||||||
Mode
|
Mode
|
||||||
Extents[]
|
Extent[4]
|
||||||
Single Indirect
|
Single Indirect
|
||||||
Double Indirect?
|
Double Indirect?
|
||||||
|
|
||||||
@@ -37,3 +38,11 @@ Directory Entry: (64B)
|
|||||||
INode Number
|
INode Number
|
||||||
Name (max length 60 Bytes)
|
Name (max length 60 Bytes)
|
||||||
|
|
||||||
|
Filetypes:
|
||||||
|
File
|
||||||
|
Directory
|
||||||
|
#TODO
|
||||||
|
Link
|
||||||
|
Device
|
||||||
|
Stream?
|
||||||
|
|
||||||
|
|||||||
+53
-60
@@ -1,90 +1,83 @@
|
|||||||
#ifndef FS_H
|
#ifndef FS_H
|
||||||
#define FS_H
|
#define FS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For info, read the fs-spec.txt document inside of docs/
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define FS_BLOCK_SIZE 4096
|
// FS Definitions
|
||||||
#define FS_SECTOR_SIZE 512
|
#define FS_SECTOR_SIZE 512
|
||||||
|
#define FS_BLOCK_SIZE 4096
|
||||||
|
|
||||||
#define FILETYPE_FILE 0
|
// Conversion Macros (beatiful)
|
||||||
#define FILETYPE_DIR 1
|
#define BYTES2BLOCKS(_n) ( (_n) == 0 ? 0 : \
|
||||||
|
(_n) <= (FS_BLOCK_SIZE) ? 1 : \
|
||||||
|
((_n) / FS_BLOCK_SIZE) + (((_n) % FS_BLOCK_SIZE) > 0 ? 1 : 0) )
|
||||||
|
|
||||||
// Filesystem structures
|
#define BYTES2SECTORS(_n) ( (_n) == 0 ? 0 : \
|
||||||
typedef struct {
|
(_n) <= (FS_SECTOR_SIZE) ? 1 : \
|
||||||
uint8_t second;
|
((_n) / FS_SECTOR_SIZE) + (((_n) % FS_SECTOR_SIZE) > 0 ? 1 : 0) )
|
||||||
uint8_t minute;
|
|
||||||
uint8_t hour;
|
// Filetypes
|
||||||
uint8_t day;
|
#define FT_FILE 0
|
||||||
uint8_t month;
|
#define FT_DIR 1
|
||||||
uint16_t year;
|
|
||||||
uint8_t reserved;
|
// FS Structures
|
||||||
} __attribute__ ((packed)) fsDatetime_t;
|
// TODO: datetime_t?
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t sectors[FS_BLOCK_SIZE / FS_SECTOR_SIZE][FS_SECTOR_SIZE];
|
uint8_t sectors[FS_BLOCK_SIZE / FS_SECTOR_SIZE][FS_SECTOR_SIZE];
|
||||||
} __attribute__ ((packed)) bootBlock_t;
|
} __attribute__ ((packed)) bootblock_t;
|
||||||
|
|
||||||
|
// Superblock - Padded to 4096 Bytes
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
// Constant data
|
||||||
|
uint16_t deviceId;
|
||||||
|
uint16_t extentsPerIndirect;
|
||||||
|
uint32_t maxFileSize;
|
||||||
|
uint16_t inodesPerSector;
|
||||||
|
|
||||||
|
// INode data
|
||||||
uint32_t inodeCount;
|
uint32_t inodeCount;
|
||||||
|
uint32_t inodeBitmapBlock;
|
||||||
|
uint32_t inodesStart;
|
||||||
|
uint32_t inodeBlockCount;
|
||||||
|
|
||||||
uint16_t firstINodeBitmapBlock;
|
// Data data :)
|
||||||
uint16_t firstDataBitmapBlock;
|
uint32_t dataBitmapBlock;
|
||||||
uint16_t inodeBitmapBlockCount;
|
uint32_t dataStart;
|
||||||
uint16_t dataBitmapBlockCount;
|
uint32_t dataBlockCount;
|
||||||
uint32_t firstINodeBlock;
|
|
||||||
uint32_t firstDataBlock;
|
|
||||||
uint16_t inodeBlockCount;
|
|
||||||
uint16_t dataBlockCount;
|
|
||||||
|
|
||||||
uint32_t maxFileSize; // in bytes
|
// Other
|
||||||
uint16_t blockSize; // in bytes
|
uint32_t rootInodePtr;
|
||||||
uint8_t inodeSize; // in bytes
|
uint32_t firstUnreservedInode;
|
||||||
|
} __attribute__ ((packed)) superblock_t;
|
||||||
uint32_t rootINodePtr;
|
|
||||||
uint8_t inodesPerBlock;
|
|
||||||
uint8_t directExtentsPerINode;
|
|
||||||
uint16_t extentsPerIndirectBlock;
|
|
||||||
uint32_t firstFreeINodeBit;
|
|
||||||
uint32_t firstFreeDataBit;
|
|
||||||
uint16_t deviceNumber;
|
|
||||||
uint8_t firstUnreservedINode;
|
|
||||||
|
|
||||||
uint8_t reserved[14];
|
|
||||||
} __attribute__ ((packed)) superBlock_t;
|
|
||||||
|
|
||||||
|
// Extent - 8 Bytes
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t firstBlock;
|
uint32_t block;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
} __attribute__ ((packed)) extent_t;
|
} __attribute__ ((packed)) extent_t;
|
||||||
|
|
||||||
|
// INode - 64 Bytes
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t id; // Idetifier
|
uint32_t id;
|
||||||
uint8_t filetype;
|
uint8_t type;
|
||||||
uint32_t sizeBytes;
|
uint32_t sizeBytes; // Size in bytes
|
||||||
uint32_t sizeSectors;
|
uint32_t sizeSectors; // Size in sectors
|
||||||
fsDatetime_t timestamp;
|
uint8_t mode; // Access permisions
|
||||||
extent_t extent[4];
|
extent_t extent[4];
|
||||||
uint32_t singleIndirectBlock;
|
uint32_t singleIndirect;
|
||||||
uint32_t doubleIndirectBlock;
|
uint32_t doubleIndirect;
|
||||||
uint8_t refCount;
|
|
||||||
uint8_t reserved[2];
|
uint8_t reserved[10];
|
||||||
} __attribute__ ((packed)) inode_t;
|
} __attribute__ ((packed)) inode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t id; // Matching ID with INode
|
|
||||||
char name[60];
|
char name[60];
|
||||||
|
uint32_t id;
|
||||||
} __attribute__ ((packed)) dirEntry_t;
|
} __attribute__ ((packed)) dirEntry_t;
|
||||||
|
|
||||||
// Utility functions
|
|
||||||
uint32_t bytesToBlocks(uint32_t bytes) {
|
|
||||||
if (bytes == 0) return 0;
|
|
||||||
if (bytes <= FS_BLOCK_SIZE) return 1;
|
|
||||||
return (bytes / FS_BLOCK_SIZE) + ((bytes % FS_BLOCK_SIZE) > 0 ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t bytesToSectors(uint32_t bytes) {
|
|
||||||
if (bytes == 0) return 0;
|
|
||||||
if (bytes <= FS_SECTOR_SIZE) return 1;
|
|
||||||
return (bytes / FS_SECTOR_SIZE) + ((bytes % FS_SECTOR_SIZE) > 0 ? 1 : 0);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+12
-20
@@ -1,44 +1,36 @@
|
|||||||
#ifndef IMPL_H
|
#ifndef IMPL_H
|
||||||
#define IMPL_H
|
#define IMPL_H
|
||||||
|
|
||||||
#include <disk/disk.h>
|
|
||||||
#include <fs/fs.h>
|
#include <fs/fs.h>
|
||||||
#include <memory/addresses.h>
|
#include <memory/addresses.h>
|
||||||
|
#include <disk/disk.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
char* currentDir;
|
char* currentDir;
|
||||||
inode_t currentDirINode;
|
|
||||||
|
|
||||||
char tempSector[FS_SECTOR_SIZE];
|
inode_t* getInode(char* path) {
|
||||||
char tempBlock[FS_BLOCK_SIZE];
|
dirEntry_t* dentry = (dirEntry_t*)SCRATCH_BLOCK_LOC;
|
||||||
|
|
||||||
inode_t rootINode;
|
while (dentry->name[0] != '\0') {
|
||||||
|
if (strcmp(dentry->name, path)) break;
|
||||||
inode_t* getINode(char* path) {
|
dentry++;
|
||||||
dirEntry_t* dirEntry = (dirEntry_t*)SCRATCH_BLOCK_LOC;
|
|
||||||
while (dirEntry->name[0] != '\0') {
|
|
||||||
if (strcmp(dirEntry->name, path) == 0) break;
|
|
||||||
dirEntry++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirEntry->name[0] == '\0') return NULL;
|
if (dentry->name[0] == '\0') return NULL;
|
||||||
|
|
||||||
inode_t* inode = (inode_t*)BOOT_FIRST_INODE_LOC;
|
inode_t* inode = (inode_t*)BOOT_FIRST_INODE_LOC;
|
||||||
while (inode->id != dirEntry->id) {
|
while (inode->id != dentry->id) { inode++; }
|
||||||
inode++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t loadFile(inode_t* inode, void* dest) {
|
uint8_t loadFile(inode_t* inode, void* dest) {
|
||||||
uint32_t totalBlocks = bytesToBlocks(inode->sizeBytes);
|
uint32_t totalBlocks = BYTES2BLOCKS(inode->sizeBytes);
|
||||||
uint32_t addressOffset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 4 && totalBlocks > 0; i++) {
|
for (uint8_t i = 0; i < 4 && totalBlocks > 0; i++) {
|
||||||
diskRead(inode->extent[i].firstBlock * 8, inode->extent[i].length * 8, dest + addressOffset);
|
diskRead(inode->extent[i].block * 8, inode->extent[i].length * 8, dest + offset);
|
||||||
addressOffset += inode->extent[i].length * FS_BLOCK_SIZE;
|
offset += inode->extent[i].length * FS_BLOCK_SIZE;
|
||||||
totalBlocks -= inode->extent[i].length;
|
totalBlocks -= inode->extent[i].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
* 0x6000-0x6fff - VBE info area
|
* 0x6000-0x6fff - VBE info area
|
||||||
* 0x7000-0x7bff - SMAP Area
|
* 0x7000-0x7bff - SMAP Area
|
||||||
* 0x7c00-0x8bff - Bootblock
|
* 0x7c00-0x8bff - Bootblock
|
||||||
* 0x8c00-0x9bff - Superblock (i think)
|
* 0x8c00-0x9bff - Superblock
|
||||||
* 0x9c00-0xafff - Free
|
* 0x9c00-0xafff - Free
|
||||||
* 0xb000-0xbfff - Bootloader first INode
|
* 0xb000-0xbfff - Bootloader first INode
|
||||||
|
* 0xc000-0xcfff - Scratch INode block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Global Variables 0x1800-0x1fff
|
// Global Variables 0x1800-0x1fff
|
||||||
|
|||||||
+53
-64
@@ -31,7 +31,7 @@ fileInfo_t files[] = { // TODO: Not have to list all of the files, loop through
|
|||||||
{ BIN_DIR"editor.bin" },
|
{ BIN_DIR"editor.bin" },
|
||||||
};
|
};
|
||||||
|
|
||||||
superBlock_t superblock = { 0 };
|
superblock_t superblock = { 0 };
|
||||||
|
|
||||||
FILE* imagePtr;
|
FILE* imagePtr;
|
||||||
uint32_t diskSize = DISK_SIZE;
|
uint32_t diskSize = DISK_SIZE;
|
||||||
@@ -63,11 +63,11 @@ int main(int argc, char** argv) {
|
|||||||
fseek(files[i].fp, 0, SEEK_END);
|
fseek(files[i].fp, 0, SEEK_END);
|
||||||
files[i].size = ftell(files[i].fp);
|
files[i].size = ftell(files[i].fp);
|
||||||
rewind(files[i].fp);
|
rewind(files[i].fp);
|
||||||
fileBlocks += bytesToBlocks(files[i].size);
|
fileBlocks += BYTES2BLOCKS(files[i].size);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Building disk image %s...\n", IMAGE_NAME);
|
printf("Building disk image %s...\n", IMAGE_NAME);
|
||||||
printf("Block size: %d Bytes, Total disk blocks: %d (%d Bytes)\n\n", FS_BLOCK_SIZE, bytesToBlocks(diskSize), diskSize);
|
printf("Block size: %d Bytes, Total disk blocks: %d (%d Bytes)\n\n", FS_BLOCK_SIZE, BYTES2BLOCKS(diskSize), diskSize);
|
||||||
|
|
||||||
printf("%d files (2 hidden)\n", fileCount); // Stage 1 and 2 is hidden
|
printf("%d files (2 hidden)\n", fileCount); // Stage 1 and 2 is hidden
|
||||||
|
|
||||||
@@ -79,12 +79,12 @@ int main(int argc, char** argv) {
|
|||||||
writeINodeBlocks();
|
writeINodeBlocks();
|
||||||
writeDataBlocks();
|
writeDataBlocks();
|
||||||
|
|
||||||
uint32_t writtenBlocks = 2 + superblock.inodeBitmapBlockCount + superblock.dataBitmapBlockCount + superblock.inodeBlockCount + superblock.dataBlockCount;
|
uint32_t writtenBlocks = 4 + superblock.inodeBlockCount + superblock.dataBlockCount;
|
||||||
printf("\nWritten blocks: %d (%d Bytes)\n", writtenBlocks, writtenBlocks * FS_BLOCK_SIZE);
|
printf("\nWritten blocks: %d (%d Bytes)\n", writtenBlocks, writtenBlocks * FS_BLOCK_SIZE);
|
||||||
printf("Free blocks: %d (%d Bytes)\n", bytesToBlocks(diskSize) - writtenBlocks, diskSize - writtenBlocks * FS_BLOCK_SIZE);
|
printf("Free blocks: %d (%d Bytes)\n", BYTES2BLOCKS(diskSize) - writtenBlocks, diskSize - writtenBlocks * FS_BLOCK_SIZE);
|
||||||
|
|
||||||
// Pad out to the whole disk size
|
// Pad out to the whole disk size
|
||||||
for (uint32_t i = 0; i < bytesToBlocks(diskSize) - writtenBlocks; i++) {
|
for (uint32_t i = 0; i < BYTES2BLOCKS(diskSize) - writtenBlocks; i++) {
|
||||||
assert(fwrite(nullBlock, FS_BLOCK_SIZE, 1, imagePtr) == 1);
|
assert(fwrite(nullBlock, FS_BLOCK_SIZE, 1, imagePtr) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,10 +98,10 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeBootblock() {
|
void writeBootblock() {
|
||||||
bootBlock_t bootBlock = { 0 };
|
bootblock_t bootBlock = { 0 };
|
||||||
assert(fread(bootBlock.sectors[0], FS_SECTOR_SIZE, 1, files[0].fp) == 1); // File 0 - Stage 1
|
assert(fread(bootBlock.sectors[0], FS_SECTOR_SIZE, 1, files[0].fp) == 1); // File 0 - Stage 1
|
||||||
|
|
||||||
for (uint8_t i = 1; i < bytesToSectors(files[i].size); i++) {
|
for (uint8_t i = 1; i < BYTES2SECTORS(files[i].size); i++) {
|
||||||
if (i > 7) {
|
if (i > 7) {
|
||||||
fprintf(stderr, "%s is too large, maximum size of bootblock is 7 sectors (%d Bytes)\n", files[1].name, 7 * FS_SECTOR_SIZE);
|
fprintf(stderr, "%s is too large, maximum size of bootblock is 7 sectors (%d Bytes)\n", files[1].name, 7 * FS_SECTOR_SIZE);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -117,33 +117,39 @@ void writeBootblock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeSuperblock() {
|
void writeSuperblock() {
|
||||||
superblock.inodeCount = fileCount; // 2 reserved INodes (0 - Invalid, 1 - Root)
|
/* Block Layout
|
||||||
superblock.firstINodeBitmapBlock = 2; // Block 0 - Boot, Block 1 - Superblock
|
* 0 - Boot
|
||||||
superblock.inodeBitmapBlockCount = superblock.inodeCount / (FS_BLOCK_SIZE * 8) + ((superblock.inodeCount % (FS_BLOCK_SIZE * 8) > 0) ? 1 : 0);
|
* 1 - Super
|
||||||
superblock.firstDataBitmapBlock = superblock.firstINodeBitmapBlock + superblock.inodeBitmapBlockCount;
|
* 2 - INode Bitmap
|
||||||
superblock.inodeBlockCount = bytesToBlocks(superblock.inodeCount * sizeof(inode_t));
|
* 3 - Data Bitmap
|
||||||
|
* 4 - First INode Block
|
||||||
|
*/
|
||||||
|
|
||||||
dataBlocks = bytesToBlocks(diskSize);
|
// Constant
|
||||||
dataBitCount = (dataBlocks - superblock.firstDataBitmapBlock - superblock.inodeBlockCount);
|
superblock.deviceId = 0x01;
|
||||||
|
superblock.extentsPerIndirect = FS_BLOCK_SIZE / sizeof(extent_t);
|
||||||
superblock.dataBitmapBlockCount = dataBitCount / (FS_BLOCK_SIZE * 8) + ((dataBitCount % (FS_BLOCK_SIZE * 8) > 0) ? 1 : 0);
|
|
||||||
superblock.firstINodeBlock = superblock.firstDataBitmapBlock + superblock.dataBitmapBlockCount;
|
|
||||||
superblock.firstDataBlock = superblock.firstINodeBlock + superblock.inodeBlockCount;
|
|
||||||
superblock.dataBlockCount = (fileBlocks - 2) + 1; // 1 Block for root dir (-1 for boot block)
|
|
||||||
superblock.maxFileSize = 0xffffffff;
|
superblock.maxFileSize = 0xffffffff;
|
||||||
superblock.blockSize = FS_BLOCK_SIZE;
|
superblock.inodesPerSector = (FS_SECTOR_SIZE / sizeof(inode_t));
|
||||||
superblock.inodeSize = sizeof(inode_t);
|
|
||||||
superblock.rootINodePtr = 0; // Gets setup at runtime
|
|
||||||
superblock.inodesPerBlock = FS_BLOCK_SIZE / sizeof(inode_t);
|
|
||||||
superblock.directExtentsPerINode = 4;
|
|
||||||
superblock.extentsPerIndirectBlock = FS_BLOCK_SIZE / sizeof(extent_t);
|
|
||||||
superblock.firstFreeINodeBit = superblock.inodeCount;
|
|
||||||
superblock.firstFreeDataBit = (fileBlocks - 2) + 1; // +1 for root dir
|
|
||||||
superblock.deviceNumber = 0x01;
|
|
||||||
superblock.firstUnreservedINode = 3; // 0 - Invalid; 1 - Root dir; 2 - Bootloader INode
|
|
||||||
|
|
||||||
assert(fwrite(&superblock, sizeof(superBlock_t), 1, imagePtr) == 1);
|
// INode
|
||||||
assert(fwrite(nullBlock, paddingBytes(sizeof(superBlock_t), FS_BLOCK_SIZE), 1, imagePtr) == 1); // Padding
|
superblock.inodeCount = fileCount + 2; // 2 reserved INodes (0 - Invalid, 1 - Root)
|
||||||
|
superblock.inodeBitmapBlock = 2;
|
||||||
|
superblock.inodesStart = 4;
|
||||||
|
superblock.inodeBlockCount = BYTES2BLOCKS(superblock.inodeCount * sizeof(inode_t));
|
||||||
|
|
||||||
|
// Data
|
||||||
|
dataBlocks = BYTES2BLOCKS(diskSize);
|
||||||
|
|
||||||
|
superblock.dataBitmapBlock = 3;
|
||||||
|
superblock.dataStart = superblock.inodesStart + superblock.inodeBlockCount;
|
||||||
|
superblock.dataBlockCount = fileBlocks; // +1 for Root, -1 for Boot
|
||||||
|
|
||||||
|
// Other
|
||||||
|
superblock.rootInodePtr = 0; // Will be filled at runtime
|
||||||
|
superblock.firstUnreservedInode = 3; // 0 - Invalid, 1 - Root, 2 - Bootloader
|
||||||
|
|
||||||
|
assert(fwrite(&superblock, sizeof(superblock_t), 1, imagePtr) == 1);
|
||||||
|
assert(fwrite(nullBlock, paddingBytes(sizeof(superblock_t), FS_BLOCK_SIZE), 1, imagePtr) == 1); // Padding
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeINodeBitmapBlocks() {
|
void writeINodeBitmapBlocks() {
|
||||||
@@ -178,50 +184,33 @@ void writeDataBitmapBlocks() {
|
|||||||
|
|
||||||
void writeINodeBlocks() {
|
void writeINodeBlocks() {
|
||||||
inode_t inode = { 0 };
|
inode_t inode = { 0 };
|
||||||
fsDatetime_t defaultTimestamp = {
|
|
||||||
.second = 12,
|
|
||||||
.minute = 12,
|
|
||||||
.hour = 12,
|
|
||||||
.day = 20,
|
|
||||||
.month = 4,
|
|
||||||
.year = 2024,
|
|
||||||
};
|
|
||||||
|
|
||||||
// INode 0 - Invalid
|
// INode 0 - Invalid
|
||||||
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
||||||
|
|
||||||
// INode 1 - Root directory
|
// INode 1 - Root directory
|
||||||
inode = (inode_t) { // OOP In C???
|
inode.id = 1;
|
||||||
.id = 1,
|
inode.type = FT_DIR;
|
||||||
.filetype = FILETYPE_DIR,
|
inode.sizeBytes = sizeof(dirEntry_t) * fileCount;
|
||||||
.sizeBytes = sizeof(dirEntry_t) * fileCount,
|
inode.sizeSectors = BYTES2SECTORS(inode.sizeBytes);
|
||||||
// .sizeSectors = bytesToSectors(inode.sizeBytes), Set below
|
// TODO: Mode
|
||||||
.timestamp = defaultTimestamp,
|
|
||||||
.extent[0] = (extent_t) {
|
|
||||||
.firstBlock = superblock.firstDataBlock,
|
|
||||||
// .length = bytesToBlocks(inode.sizeBytes), Set below
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
inode.sizeSectors = bytesToSectors(inode.sizeBytes);
|
inode.extent[0].block = superblock.dataStart;
|
||||||
inode.extent[0].length = bytesToBlocks(inode.sizeBytes);
|
inode.extent[0].length = BYTES2BLOCKS(inode.sizeBytes);
|
||||||
|
|
||||||
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
||||||
|
|
||||||
// INode 2 - Bootloader (stage 3) followed by other INodes
|
// INode 2 - Bootloader (stage 3) followed by other INodes
|
||||||
uint32_t block = superblock.firstDataBlock + inode.extent[0].length;
|
uint32_t block = superblock.dataStart + inode.extent[0].length;
|
||||||
for (uint32_t i = 2; i < fileCount; i++) {
|
for (uint32_t i = 2; i < fileCount; i++) {
|
||||||
memset(&inode, 0, sizeof(inode));
|
memset(&inode, 0, sizeof(inode));
|
||||||
inode.id = i;
|
inode.id = i;
|
||||||
inode.filetype = FILETYPE_FILE;
|
inode.type = FT_FILE;
|
||||||
inode.sizeBytes = files[i].size;
|
inode.sizeBytes = files[i].size;
|
||||||
inode.sizeSectors = bytesToSectors(inode.sizeBytes);
|
inode.sizeSectors = BYTES2SECTORS(inode.sizeBytes);
|
||||||
inode.timestamp = defaultTimestamp;
|
|
||||||
inode.extent[0] = (extent_t) {
|
inode.extent[0].block = block,
|
||||||
.firstBlock = block,
|
inode.extent[0].length = BYTES2BLOCKS(inode.sizeBytes);
|
||||||
// .length = bytesToBlocks(inode.sizeBytes),
|
|
||||||
};
|
|
||||||
inode.extent[0].length = bytesToBlocks(inode.sizeBytes);
|
|
||||||
|
|
||||||
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
||||||
|
|
||||||
@@ -248,12 +237,12 @@ void writeDataBlocks() {
|
|||||||
assert(fwrite(&dirEntry, sizeof(dirEntry), 1, imagePtr) == 1);
|
assert(fwrite(&dirEntry, sizeof(dirEntry), 1, imagePtr) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Padd out
|
// Pad out
|
||||||
assert(fwrite(nullBlock, paddingBytes(fileCount * sizeof(dirEntry_t), FS_BLOCK_SIZE), 1, imagePtr) == 1);
|
assert(fwrite(nullBlock, paddingBytes(fileCount * sizeof(dirEntry_t), FS_BLOCK_SIZE), 1, imagePtr) == 1);
|
||||||
|
|
||||||
// Write actual file data
|
// Write actual file data
|
||||||
for (uint32_t i = 2; i < fileCount; i++) {
|
for (uint32_t i = 2; i < fileCount; i++) {
|
||||||
uint32_t blockCount = bytesToBlocks(files[i].size);
|
uint32_t blockCount = BYTES2BLOCKS(files[i].size);
|
||||||
uint32_t bytesWritten = 0;
|
uint32_t bytesWritten = 0;
|
||||||
|
|
||||||
printf("%s, %d Bytes -> %d Blocks\n", files[i].name, files[i].size, blockCount);
|
printf("%s, %d Bytes -> %d Blocks\n", files[i].name, files[i].size, blockCount);
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
[org 0x7c00]
|
[org 0x7c00]
|
||||||
|
|
||||||
%define SUPERBLOCK 0x8c00
|
%define SUPERBLOCK 0x8c00
|
||||||
%define FIRST_INODE_BLOCK (SUPERBLOCK) + 12
|
%define FIRST_INODE_BLOCK (SUPERBLOCK) + 18
|
||||||
%define STAGE3_INODE 0xb000 + 128
|
%define STAGE3_INODE 0xb000 + (2 * 64)
|
||||||
%define EXTENT0 (STAGE3_INODE) + 21 ; Offset of extent[0] in inode_t
|
%define EXTENT0 (STAGE3_INODE) + 14 ; Offset of extent[0] in inode_t
|
||||||
|
|
||||||
start:
|
start:
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
|
|||||||
+5
-5
@@ -27,16 +27,16 @@ void main() {
|
|||||||
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
|
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
|
||||||
|
|
||||||
// Load root dir, find kernel INode and parse it
|
// Load root dir, find kernel INode and parse it
|
||||||
superBlock_t* superblock = (superBlock_t*)SUPERBLOCK_LOC;
|
superblock_t* superblock = (superblock_t*)SUPERBLOCK_LOC;
|
||||||
superblock->rootINodePtr = BOOT_FIRST_INODE_LOC + sizeof(inode_t);
|
superblock->rootInodePtr = BOOT_FIRST_INODE_LOC + sizeof(inode_t);
|
||||||
diskRead(superblock->firstDataBlock * 8, 8, (void*)SCRATCH_BLOCK_LOC);
|
diskRead(superblock->dataStart * 8, 8, (void*)SCRATCH_BLOCK_LOC);
|
||||||
|
|
||||||
inode_t* inode;
|
inode_t* inode;
|
||||||
if ((inode = getINode("kernel.bin")) == NULL) {
|
if ((inode = getInode("kernel.bin")) == NULL) {
|
||||||
__asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
__asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
||||||
} else { loadFile(inode, (void*)KERNEL_LOC); }
|
} else { loadFile(inode, (void*)KERNEL_LOC); }
|
||||||
|
|
||||||
if ((inode = getINode("term16n.fnt")) == NULL) {
|
if ((inode = getInode("term16n.fnt")) == NULL) {
|
||||||
__asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
__asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
||||||
} else { loadFile(inode, (void*)FONT_LOC); }
|
} else { loadFile(inode, (void*)FONT_LOC); }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user