Espresso 0.0.1c
This commit is contained in:
@ -1,248 +0,0 @@
|
||||
#include <drivers/ide.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fs/fat16.h>
|
||||
|
||||
static fat16_t fat;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint8_t jmp[3];
|
||||
char oem[8];
|
||||
uint16_t bytes_per_sector;
|
||||
uint8_t sectors_per_cluster;
|
||||
uint16_t reserved_sectors;
|
||||
uint8_t fat_count;
|
||||
uint16_t root_entries;
|
||||
uint16_t total_sectors_short;
|
||||
uint8_t media_desc;
|
||||
uint16_t fat_size_sectors;
|
||||
uint16_t sectors_per_track;
|
||||
uint16_t heads;
|
||||
uint32_t hidden_sectors;
|
||||
uint32_t total_sectors_long;
|
||||
// Extended Boot Record...
|
||||
} fat16_bpb_t;
|
||||
|
||||
typedef struct {
|
||||
char name[8];
|
||||
char ext[3];
|
||||
uint8_t attr;
|
||||
uint8_t reserved;
|
||||
uint8_t create_time_tenth;
|
||||
uint16_t create_time;
|
||||
uint16_t create_date;
|
||||
uint16_t access_date;
|
||||
uint16_t first_cluster_hi;
|
||||
uint16_t write_time;
|
||||
uint16_t write_date;
|
||||
uint16_t first_cluster_lo;
|
||||
uint32_t size;
|
||||
} fat16_direntry_raw_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
static uint8_t sector_buffer[512];
|
||||
|
||||
uint32_t cluster_to_lba(uint16_t cluster)
|
||||
{
|
||||
return fat.data_start + ((cluster - 2) * fat.sectors_per_cluster);
|
||||
}
|
||||
|
||||
|
||||
int32_t fat16_init(uint8_t drive)
|
||||
{
|
||||
if (ide_read48(drive, 0, 1, sector_buffer) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fat16_bpb_t* bpb = (fat16_bpb_t*)sector_buffer;
|
||||
|
||||
fat.drive = drive;
|
||||
fat.bytes_per_sector = bpb->bytes_per_sector;
|
||||
fat.sectors_per_cluster = bpb->sectors_per_cluster;
|
||||
fat.root_entry_count = bpb->root_entries;
|
||||
|
||||
fat.fat_start = bpb->reserved_sectors;
|
||||
fat.root_dir_start = fat.fat_start + bpb->fat_count * bpb->fat_size_sectors;
|
||||
fat.data_start = fat.root_dir_start + ((bpb->root_entries * 32 + fat.bytes_per_sector - 1) / fat.bytes_per_sector);
|
||||
fat.current_dir_cluster = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t fat16_get_fat_entry(uint16_t cluster)
|
||||
{
|
||||
uint32_t fat_offset = cluster * 2;
|
||||
uint32_t fat_sector = fat.fat_start + (fat_offset / fat.bytes_per_sector);
|
||||
uint32_t ent_offset = fat_offset % fat.bytes_per_sector;
|
||||
|
||||
if (ide_read48(fat.drive, fat_sector, 1, sector_buffer) < 0)
|
||||
{
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
return *(uint16_t*)§or_buffer[ent_offset];
|
||||
}
|
||||
|
||||
uint16_t fat16_alloc_cluster(void)
|
||||
{
|
||||
for (uint16_t cluster = 2; cluster < 0xFFF0; ++cluster) {
|
||||
uint16_t entry = fat16_get_fat_entry(cluster);
|
||||
if (entry == 0x0000) {
|
||||
// Mark as end of chain
|
||||
uint32_t fat_offset = cluster * 2;
|
||||
uint32_t fat_sector = fat.fat_start + (fat_offset / fat.bytes_per_sector);
|
||||
uint32_t ent_offset = fat_offset % fat.bytes_per_sector;
|
||||
|
||||
if (ide_read48(fat.drive, fat_sector, 1, sector_buffer) < 0) return 0;
|
||||
*(uint16_t*)§or_buffer[ent_offset] = 0xFFFF;
|
||||
if (ide_write48(fat.drive, fat_sector, 1, sector_buffer) < 0) return 0;
|
||||
|
||||
return cluster;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t fat16_list_dir(fat16_dir_entry_t* entries, size_t max_entries)
|
||||
{
|
||||
size_t count = 0;
|
||||
if (fat.current_dir_cluster == 0)
|
||||
{
|
||||
uint16_t root_sectors = ((fat.root_entry_count * 32) + (fat.bytes_per_sector - 1)) / fat.bytes_per_sector;
|
||||
for (uint32_t i = 0; i < root_sectors && count < max_entries; ++i)
|
||||
{
|
||||
if (ide_read48(fat.drive, fat.root_dir_start + i, 1, sector_buffer) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fat16_direntry_raw_t* de = (fat16_direntry_raw_t*)sector_buffer;
|
||||
for (int32_t j = 0; j < 512 / 32 && count < max_entries; ++j, ++de)
|
||||
{
|
||||
if (de->name[0] == 0x00 || de->name[0] == 0xE5)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(entries[count].name, de->name, 8);
|
||||
entries[count].name[8] = '\0';
|
||||
entries[count].attr = de->attr;
|
||||
entries[count].cluster = de->first_cluster_lo;
|
||||
entries[count].size = de->size;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TODO: Add support for listing subdirectories if current_dir_cluster != 0 */
|
||||
return count;
|
||||
}
|
||||
|
||||
int32_t fat16_read_file(const char* filename, void* buffer, size_t max_size) {
|
||||
fat16_dir_entry_t entries[64];
|
||||
int32_t n = fat16_list_dir(entries, 64);
|
||||
for (int32_t i = 0; i < n; ++i) {
|
||||
if (!(entries[i].attr & FAT16_ATTR_DIRECTORY) &&
|
||||
strncmp(entries[i].name, filename, FAT16_MAX_FILENAME) == 0) {
|
||||
|
||||
uint16_t cluster = entries[i].cluster;
|
||||
uint8_t* out = (uint8_t*)buffer;
|
||||
size_t remaining = entries[i].size < max_size ? entries[i].size : max_size;
|
||||
|
||||
while (cluster >= 0x0002 && cluster < 0xFFF8 && remaining > 0) {
|
||||
uint32_t lba = cluster_to_lba(cluster);
|
||||
size_t to_read = fat.bytes_per_sector * fat.sectors_per_cluster;
|
||||
|
||||
if (ide_read48(fat.drive, lba, fat.sectors_per_cluster, sector_buffer) < 0)
|
||||
return -1;
|
||||
|
||||
size_t copy_size = (remaining < to_read) ? remaining : to_read;
|
||||
memcpy(out, sector_buffer, copy_size);
|
||||
out += copy_size;
|
||||
remaining -= copy_size;
|
||||
|
||||
cluster = fat16_get_fat_entry(cluster);
|
||||
}
|
||||
|
||||
return (int32_t)(out - (uint8_t*)buffer);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int32_t fat16_write_file(const char* filename, const void* data, size_t size) {
|
||||
fat16_dir_entry_t entries[64];
|
||||
int32_t n = fat16_list_dir(entries, 64);
|
||||
for (int32_t i = 0; i < n; ++i) {
|
||||
if (strncmp(entries[i].name, filename, FAT16_MAX_FILENAME) == 0) {
|
||||
uint16_t cluster = entries[i].cluster;
|
||||
const uint8_t* src = (const uint8_t*)data;
|
||||
size_t remaining = size;
|
||||
|
||||
while (remaining > 0) {
|
||||
uint32_t lba = cluster_to_lba(cluster);
|
||||
size_t cluster_bytes = fat.sectors_per_cluster * fat.bytes_per_sector;
|
||||
size_t to_write = remaining < cluster_bytes ? remaining : cluster_bytes;
|
||||
|
||||
memset(sector_buffer, 0, cluster_bytes); // Clear old data
|
||||
memcpy(sector_buffer, src, to_write);
|
||||
if (ide_write48(fat.drive, lba, fat.sectors_per_cluster, sector_buffer) < 0)
|
||||
return -1;
|
||||
|
||||
src += to_write;
|
||||
remaining -= to_write;
|
||||
|
||||
// Last chunk?
|
||||
if (remaining == 0)
|
||||
break;
|
||||
|
||||
// Check next cluster
|
||||
uint16_t next = fat16_get_fat_entry(cluster);
|
||||
if (next >= 0xFFF8 || next == 0x0000) {
|
||||
// Need to allocate a new cluster
|
||||
uint16_t new_cluster = fat16_alloc_cluster();
|
||||
if (new_cluster == 0) return -1;
|
||||
|
||||
// Update FAT to point to new cluster
|
||||
uint32_t fat_offset = cluster * 2;
|
||||
uint32_t fat_sector = fat.fat_start + (fat_offset / fat.bytes_per_sector);
|
||||
uint32_t ent_offset = fat_offset % fat.bytes_per_sector;
|
||||
|
||||
if (ide_read48(fat.drive, fat_sector, 1, sector_buffer) < 0) return -1;
|
||||
*(uint16_t*)§or_buffer[ent_offset] = new_cluster;
|
||||
if (ide_write48(fat.drive, fat_sector, 1, sector_buffer) < 0) return -1;
|
||||
|
||||
next = new_cluster;
|
||||
}
|
||||
|
||||
cluster = next;
|
||||
}
|
||||
|
||||
return (int32_t)size;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t fat16_change_dir(const char* dirname)
|
||||
{
|
||||
fat16_dir_entry_t entries[64];
|
||||
int32_t n = fat16_list_dir(entries, 64);
|
||||
for (int32_t i = 0; i < n; ++i)
|
||||
{
|
||||
if ((entries[i].attr & FAT16_ATTR_DIRECTORY) && strncmp(entries[i].name, dirname, FAT16_MAX_FILENAME) == 0)
|
||||
{
|
||||
fat.current_dir_cluster = entries[i].cluster;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
94
drivers/fs/sfs.c
Normal file
94
drivers/fs/sfs.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <drivers/ide.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fs/sfs.h>
|
||||
|
||||
|
||||
#define SFS_BEGINNING_LBA 8
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct sfs_file_header {
|
||||
uint16_t magic; /* 0xBEEF */
|
||||
/*
|
||||
32 chars for the filename itself,
|
||||
4 chars for the file's extension,
|
||||
and 1 char for the null zero.
|
||||
*/
|
||||
char filename[37];
|
||||
|
||||
uint64_t data_beginning; /* Actually a 48 bit LBA mind you */
|
||||
uint32_t num_sectors; /* Number of sectors after data_beginning that are this file's data */
|
||||
|
||||
uint8_t padding[13]; /* Padding to 64 bytes total */
|
||||
} sfs_file_header_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
static sfs_file_header_t* base;
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t sfs_init(bool format)
|
||||
{
|
||||
uint8_t buffer[512] = { 0 };
|
||||
|
||||
int32_t kl = read_sector(SFS_BEGINNING_LBA, buffer);
|
||||
|
||||
if (kl != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
volatile sfs_file_header_t null_file;
|
||||
memcpy(&null_file, buffer, sizeof(sfs_file_header_t));
|
||||
|
||||
if ((&null_file)->magic != 0xBEEF)
|
||||
{
|
||||
if (!format)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
//sfs_format();
|
||||
return -2;
|
||||
}
|
||||
|
||||
memcpy(base, &null_file, sizeof(sfs_file_header_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool sfs_get_formatted_name(const char* raw_name, char output[37])
|
||||
{
|
||||
size_t len = strlen(raw_name);
|
||||
|
||||
if (len > 36 || strchr(raw_name, '/') || strchr(raw_name, '*') || strchr(raw_name, '\\')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(output, ' ', 36);
|
||||
output[36] = '\0';
|
||||
|
||||
memcpy(output, raw_name, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Note: if a negative value is passed for num, then read the whole file
|
||||
*/
|
||||
int32_t sfs_read_file(char* _name, void* buffer, uint32_t num)
|
||||
{
|
||||
char name[37] = { '\0' };
|
||||
|
||||
if (sfs_get_formatted_name(_name, name))
|
||||
{
|
||||
return -128;
|
||||
}
|
||||
|
||||
printf("%s", name);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,30 +1,32 @@
|
||||
/*#include <fs/fat16.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <fs/vfs.h>*/
|
||||
#include <fs/vfs.h>
|
||||
|
||||
|
||||
typedef struct vfs_file_header {
|
||||
char* filename; /* The filename, not the path. */
|
||||
|
||||
int32_t fd;
|
||||
|
||||
uint8_t type_info; /* Bits 0 - 3 -> File type, Bits 4 - 7 FS type */
|
||||
|
||||
uint16_t* fs_header;
|
||||
|
||||
struct vfs_file_header* next; /* Linked list */
|
||||
} vfs_file_header_t;
|
||||
|
||||
|
||||
vfs_file_header_t* root;
|
||||
|
||||
|
||||
/*
|
||||
Note: the special FILE value -128 means the current directory.
|
||||
-32 means stdin
|
||||
-33 means stdout (which can be read)
|
||||
*/
|
||||
|
||||
/*bool vfs_initialized = false;
|
||||
ramfs_file_header_t* vfs_current_dir = NULL;
|
||||
|
||||
void vfs_init(void)
|
||||
{
|
||||
if (!vfs_initialized)
|
||||
{
|
||||
ramfs_init();
|
||||
|
||||
ramfs_make_root();
|
||||
This is being written as a test.
|
||||
This has no affect on aaand my CPU is at 87 degrees Celsius and /usr/bin/gnome-shell is at 115% CPU utilization.
|
||||
Just by writing that.
|
||||
wow.
|
||||
and now my CPU fan is going nuts.
|
||||
|
||||
vfs_initialized = true;
|
||||
vfs_current_dir = ramfs_get_root();
|
||||
}
|
||||
}
|
||||
|
||||
--update: now it works. I had to go back to nouveau instead of the proprietary nVidia drivers..
|
||||
*/
|
||||
|
Reference in New Issue
Block a user