basic fs type stuff, fat16, removing stack segment and using data segment

This commit is contained in:
Benji Dial 2020-05-24 21:55:12 -04:00
parent 02f14113cb
commit 021ea9b271
13 changed files with 252 additions and 79 deletions

View file

@ -1,3 +1,2 @@
0x08: 0x0000.0000 - 0x0007.ffff (code) 0x08: 0x0000.0000 - 0x0007.ffff (code)
0x10: 0x0000.0000 - 0x000f.ffff (data) 0x10: 0x0000.0000 - 0x000f.ffff (data)
0x18: 0x0003.8000 - 0x0003.ffff (stack)

View file

@ -1,8 +1,7 @@
0x0001.0000 - 0x0002.5fff: unused 0x0001.0000 - 0x0001.ffff: unused
0x0002.6000 - 0x0002.bfff: fat 0x0002.0000 - 0x0002.7fff: fat
0x0002.8000 - 0x0002.bfff: unused
0x0002.c000 - 0x0002.ffff: file buffers 0x0002.c000 - 0x0002.ffff: file buffers
0x0003.0000 - 0x0003.7fff: kernel 0x0003.0000 - 0x0003.7fff: kernel
0x0003.8000 - 0x0003.ffff: stack 0x0003.8000 - 0x0003.ffff: stack
0x0004.0000 - 0x0007.ffff: unused 0x0004.0000 - 0x000f.ffff: unused
0x0008.0000 - 0x000d.9fff: ramd
0x000d.a000 - 0xffff.ffff: unused

View file

@ -1,6 +1,6 @@
disk: kernel boot disk: kernel boot
mkdir -p obj out mkdir -p obj out
/sbin/mkfs.fat -C -f 1 -F 12 -n "PORTLAND OS" -R 17 obj/shadow.img 8192 /sbin/mkfs.fat -C -f 1 -F 16 -n "PORTLAND OS" -R 17 -s 1 -S 512 obj/shadow.img 8192
echo -n -e '\xeb\x3c' > obj/jmp.bin echo -n -e '\xeb\x3c' > obj/jmp.bin
dd if=obj/jmp.bin of=obj/shadow.img obs=2 conv=notrunc dd if=obj/jmp.bin of=obj/shadow.img obs=2 conv=notrunc
dd if=out/boot.bin of=obj/shadow.img obs=1 seek=62 conv=notrunc dd if=out/boot.bin of=obj/shadow.img obs=1 seek=62 conv=notrunc

View file

@ -39,9 +39,8 @@ bits 32
pmode: pmode:
mov ax, 0x10 mov ax, 0x10
mov ds, ax mov ds, ax
mov ax, 0x18
mov ss, ax mov ss, ax
mov esp, 0x00008000 mov esp, 0x00040000
xor ebp, ebp xor ebp, ebp
call kernel_segment * 16 call kernel_segment * 16
@ -57,7 +56,6 @@ gdt:
dq 0x0000_0000_0000_0000 dq 0x0000_0000_0000_0000
dq 0x00c0_9a00_0000_007f dq 0x00c0_9a00_0000_007f
dq 0x00c0_9200_0000_00ff dq 0x00c0_9200_0000_00ff
dq 0x0040_9203_8000_7fff
.e: .e:
times $$ + 448 - $ db 0 times $$ + 448 - $ db 0

View file

@ -1,21 +1,87 @@
#include "fat.h" #include "fat.h"
#include "ata.h" #include "ata.h"
#include "panic.h" #include "panic.h"
#include "fs.h"
void load_fat() { void load_fat() {
read_sectors(FAT_INFO->reserved_sectors, FAT_INFO->sectors_per_fat, FAT); read_sectors(FAT_INFO->reserved_sectors, FAT_INFO->sectors_per_fat, FAT);
} }
uint16_t get_cluster(uint16_t n) { bool check_fat_name(uint8_t *fname, uint8_t *sname) {
uint32_t t = *(uint32_t *)(FAT + (n / 2) * 3); panic("Not implemented (check_fat_name)");
return (n % 2 ? (t >> 12) : t) & 0xfff;
} }
void set_cluster(uint16_t n, uint16_t v) { bool check_fat_names(uint8_t *lname, uint8_t *rname) {
uint32_t *t = (uint32_t *)(FAT + (n / 2) * 3); return (* (uint32_t *)lname == *(uint32_t *)rname) &&
*t = (*t & (n % 2 ? 0xff000fff : 0xfffff000)) | (n % 2 ? v << 12 : v); (*((uint32_t *)lname + 1) == *((uint32_t *)rname + 1)) &&
(*((uint16_t *)lname + 4) == *((uint16_t *)rname + 4)) &&
(*( lname + 10) == *( rname + 10));
} }
uint16_t get_start_cluster(uint8_t *path) { struct directory_entry buffer[16];
panic("Not implemented (get_start_cluster)."); uint16_t dir_start, buffer_from;
void load_root() {
dir_start = FAT_INFO->reserved_sectors + FAT_INFO->sectors_per_fat;
}
struct directory_entry *load_subentry(uint8_t *name) {
struct directory_entry *ptr = buffer;
uint16_t dir_current = dir_start;
do
if (((ptr == buffer + 16) && !read_sectors(buffer_from = dir_current++, 1, ptr = buffer)) || !ptr->name[0])
return 0;
while (!check_fat_name(ptr->name, name));
return ptr;
}
bool load_subdir(uint8_t *name) {
struct directory_entry *e = load_subentry(name);
if (!e)
return true;
dir_start = e->first_cluster;
return false;
}
struct directory_entry *load_entry(uint8_t *path) {
load_root();
for (uint8_t *ptr = path; ptr; ++ptr)
if (*ptr = '/') {
*ptr = 0;
if (load_subdir(path))
return 0;
path = ptr + 1;
}
return load_subentry(path);
}
bool get_entry(uint8_t *path, struct directory_entry *at) {
struct directory_entry *e = load_entry(path);
if (!e)
return true;
*at = *e;
return false;
}
bool update_entry(uint8_t *path, struct directory_entry *value) {
struct directory_entry *e = load_entry(path);
if (!e)
return true;
*e = *value;
write_sectors(buffer_from, 1, buffer);
return false;
}
bool create_entry(uint8_t *dir_path, struct directory_entry *value) {
fs_handle h = fs_open(dir_path);
struct directory_entry *check;
while (fs_read(h, 32, check))
if (check_fat_names(check->name, value->name)) {
fs_close(h);
return true;
}
fs_write(h, 32, value);
fs_close(h);
return false;
} }

View file

@ -1,4 +1,5 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#define FAT_INFO ((struct fat_info *)0x7c03) #define FAT_INFO ((struct fat_info *)0x7c03)
@ -24,9 +25,37 @@ struct fat_info {
uint8_t fs_type[8]; uint8_t fs_type[8];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define FAT ((void *)0x00026000) enum {
void load_fat(); FA_READ_ONLY = 0x01,
uint16_t get_cluster(uint16_t n); FA_HIDDEN = 0x02,
void set_cluster(uint16_t n, uint16_t v); FA_SYSTEM = 0x04,
FA_LABEL = 0x08,
FA_DIRECTORY = 0x10,
FA_ARCHIVE = 0x20,
uint16_t get_start_cluster(uint8_t *path); FA_LFN = 0x0f
};
struct directory_entry {
uint8_t name[11];
uint8_t attrib;
uint8_t name_case;
uint8_t created_decimal;
uint16_t created_time;
uint16_t created_date;
uint16_t accessed_date;
uint16_t ignore;
uint16_t modified_time;
uint16_t modified_date;
uint16_t first_cluster;
uint32_t length;
} __attribute__ ((packed));
#define FAT ((uint16_t *)0x00020000)
void load_fat();
#define CTOS(c) (FAT_INFO->reserved_sectors + FAT_INFO->sectors_per_fat + (FAT_INFO->root_entries >> 4) + (c) - 2)
bool get_entry(uint8_t *path, struct directory_entry *at);
bool update_entry(uint8_t *path, struct directory_entry *value);
bool create_entry(uint8_t *path, struct directory_entry *value);

View file

@ -4,17 +4,26 @@
#include "fat.h" #include "fat.h"
#include <stdbool.h> #include <stdbool.h>
#include "panic.h" #include "panic.h"
#include "util.h"
#define MAX_HANDLES 32 #define MAX_HANDLES 32
#define FILE_BUFFER(h) ((void *)(0x0002be00 + (h << 9))) #define FILE_BUFFER(h) ((void *)(0x0002be00 + (h << 9)))
#define HANDLE(h) ((handles - 1)[h]) #define HANDLE(h) ((handles - 1)[h])
#define HEAD(h) (FILE_BUFFER(h) + HANDLE(h).seek % 512) #define HEAD(h) (FILE_BUFFER(h) + HANDLE(h).seek % 512)
enum {
FH_DIRTY = 0x01,
FH_NO_WRITE = 0x02,
FH_NO_EXPAND = 0x04,
FH_ROOT = 0x08
};
struct handle_info { struct handle_info {
uint16_t start_cluster; uint16_t first_cluster;
uint16_t seek;
uint16_t loaded_cluster; uint16_t loaded_cluster;
bool dirty; uint32_t seek;
uint32_t length;
uint8_t flags;
}; };
struct handle_info handles[MAX_HANDLES]; struct handle_info handles[MAX_HANDLES];
@ -22,61 +31,114 @@ struct handle_info handles[MAX_HANDLES];
void clear_fs_handles() { void clear_fs_handles() {
struct handle_info *f = handles; struct handle_info *f = handles;
while (f < handles + MAX_HANDLES) while (f < handles + MAX_HANDLES)
(f++)->start_cluster = 0; (f++)->first_cluster = 0;
} }
fs_handle next_handle() { fs_handle next_handle() {
fs_handle r = 0; fs_handle r = 0;
while (HANDLE(++r).start_cluster) while (HANDLE(++r).first_cluster)
if (r == MAX_HANDLES) if (r == MAX_HANDLES)
return 0; return 0;
return r; return r;
} }
void write_buffer(fs_handle handle) { void write_buffer(fs_handle handle) {
HANDLE(handle).dirty = false; HANDLE(handle).flags &= ~FH_DIRTY;
panic("Not implemented (write_buffer)."); if (HANDLE(handle).flags & FH_ROOT)
write_sectors(HANDLE(handle).loaded_cluster, 1, FILE_BUFFER(handle));
else
write_sectors(CTOS(HANDLE(handle).loaded_cluster), 1, FILE_BUFFER(handle));
} }
void read_buffer(fs_handle handle) { void read_buffer(fs_handle handle) {
if (HANDLE(handle).dirty) if (HANDLE(handle).flags & FH_DIRTY)
write_buffer(handle); write_buffer(handle);
HANDLE(handle).loaded_cluster = HANDLE(handle).seek >> 9; uint16_t s = HANDLE(handle).seek >> 9;
panic("Not implemented (read_buffer)."); if (HANDLE(handle).flags & FH_ROOT) {
HANDLE(handle).loaded_cluster = HANDLE(handle).first_cluster + s;
read_sectors(HANDLE(handle).first_cluster + s, 1, FILE_BUFFER(handle));
}
else {
uint16_t c = HANDLE(handle).first_cluster;
while (s--)
c = FAT[c];
HANDLE(handle).loaded_cluster = c;
read_sectors(CTOS(c), 1, FILE_BUFFER(handle));
}
} }
fs_handle fs_open(uint8_t *path) { fs_handle fs_open(uint8_t *path) {
fs_handle next = next_handle(); fs_handle next = next_handle();
if (!next) if (!next)
return 0; return 0;
uint16_t s = get_start_cluster(path); struct directory_entry e;
if (!s) if (get_entry(path, &e))
return 0; return 0;
HANDLE(next).start_cluster = s; HANDLE(next).first_cluster = e.first_cluster;
HANDLE(next).seek = 0; HANDLE(next).seek = 0;
HANDLE(next).dirty = false; HANDLE(next).length = e.length;
HANDLE(next).flags = (e.attrib & FA_READ_ONLY ? FH_NO_WRITE : 0) |
(e.attrib & FA_SYSTEM ? FH_NO_EXPAND : 0);
read_buffer(next); read_buffer(next);
return next; return next;
} }
int16_t fs_seek(fs_handle handle, int16_t by) { fs_handle fs_open_root() {
uint16_t old = HANDLE(handle).seek; fs_handle next = next_handle();
uint16_t to = -by > old ? 0 : old + by; if (!next)
return 0;
HANDLE(next).first_cluster = FAT_INFO->reserved_sectors + FAT_INFO->sectors_per_fat;
HANDLE(next).seek = 0;
HANDLE(next).length = FAT_INFO->root_entries * 32;
HANDLE(next).flags = FH_NO_EXPAND | FH_ROOT;
read_buffer(next);
return next;
}
int32_t fs_seek(fs_handle handle, int32_t by) {
uint32_t old = HANDLE(handle).seek;
uint32_t to = -by > old ? 0 : old + by > HANDLE(handle).length ? HANDLE(handle).length : old + by;
HANDLE(handle).seek = to; HANDLE(handle).seek = to;
if ((to ^ old) & 0xfe00) if ((to ^ old) & 0xfe00)
read_buffer(handle); read_buffer(handle);
return to - old;
} }
uint16_t fs_read(fs_handle handle, uint16_t max, void *buffer) { uint32_t fs_read(fs_handle handle, uint32_t max, void *buffer) {
panic("Not implemented (fs_read)."); max = HANDLE(handle).seek + max > HANDLE(handle).length ? HANDLE(handle).length - HANDLE(handle).seek : max;
uint32_t left = max, eos = 512 - (HANDLE(handle).seek & 0x1ff);
if (left < eos) {
memcpy(buffer, FILE_BUFFER(handle) + (HANDLE(handle).seek & 0x1ff), left);
HANDLE(handle).seek += left;
return max;
}
memcpy(buffer, FILE_BUFFER(handle) + (HANDLE(handle).seek & 0x1ff), eos);
left -= eos;
buffer += eos;
HANDLE(handle).seek += eos;
while (left >= 512) {
read_buffer(handle);
memcpy(buffer, FILE_BUFFER(handle), 512);
left -= 512;
buffer += 512;
HANDLE(handle).seek += 512;
}
if (left) {
read_buffer(handle);
memcpy(buffer, FILE_BUFFER(handle), left);
HANDLE(handle).seek += left;
}
return max;
} }
uint16_t fs_write(fs_handle handle, uint16_t max, void *buffer) { uint32_t fs_write(fs_handle handle, uint32_t max, void *buffer) {
if (HANDLE(handle).flags & FH_NO_WRITE)
return 0;
panic("Not implemented (fs_write)."); panic("Not implemented (fs_write).");
} }
void fs_close(fs_handle handle) { void fs_close(fs_handle handle) {
if (HANDLE(handle).dirty) if (HANDLE(handle).flags & FH_DIRTY)
write_buffer(handle); write_buffer(handle);
HANDLE(handle).start_cluster = 0; HANDLE(handle).first_cluster = 0;
} }

View file

@ -4,7 +4,8 @@ void clear_fs_handles();
typedef uint8_t fs_handle; typedef uint8_t fs_handle;
fs_handle fs_open(uint8_t *path); fs_handle fs_open(uint8_t *path);
int16_t fs_seek(fs_handle handle, int16_t by); fs_handle fs_open_root();
uint16_t fs_read(fs_handle handle, uint16_t max, void *buffer); int32_t fs_seek(fs_handle handle, int32_t by);
uint16_t fs_write(fs_handle handle, uint16_t max, void *buffer); uint32_t fs_read(fs_handle handle, uint32_t max, void *buffer);
uint32_t fs_write(fs_handle handle, uint32_t max, void *buffer);
void fs_close(fs_handle handle); void fs_close(fs_handle handle);

View file

@ -16,21 +16,43 @@ void main() {
vga_printsz("\n Serial ready."); vga_printsz("\n Serial ready.");
load_fat(); load_fat();
clear_fs_handles(); clear_fs_handles();
vga_printsz("\n File system ready.\n\nDisk label: "); vga_printsz("\n File system ready.\n\nDisk info:\n Disk label: ");
vga_printsn(FAT_INFO->label, 11); vga_printsn(FAT_INFO->label, 11);
vga_printsz("\nDisk size: "); vga_printsz("\n Disk size: ");
u32_dec(FAT_INFO->sectors >> 1, nbuf); u16_dec(FAT_INFO->sectors >> 1, nbuf);
vga_printsz(nbuf); vga_printsz(nbuf);
vga_printsz("k\n\nFAT start:\n"); vga_printsz("k\n FAT size: ");
nbuf[3] = 0; u16_dec(FAT_INFO->sectors_per_fat >> 1, nbuf);
for (uint8_t r = 0; r < 192; r += 24) { vga_printsz(nbuf);
for (uint8_t c = 0; c < 24; ++c) { vga_printsz("k\n Root size: ");
u8_hex(*(uint8_t *)(FAT + r + c), nbuf); u16_dec(FAT_INFO->root_entries >> 5, nbuf);
nbuf[2] = ' '; vga_printsz(nbuf);
vga_printsz(nbuf); vga_printsz("k\n\nRoot directory:");
} fs_handle root = fs_open_root();
vga_printch('\n'); struct directory_entry e;
while(1) {
fs_read(root, 32, &e);
if (!e.name[0])
break;
if (e.attrib == FA_LFN)
continue;
uint8_t *p = (uint8_t *)&e;
nbuf[3] = 0;
vga_printsz("\n ");
vga_printsn((uint8_t *)&e.name, 11);
vga_printsz(" | 0x");
u8_hex(e.attrib, nbuf);
vga_printsz(nbuf);
vga_printch(' ');
vga_printch(e.attrib & FA_READ_ONLY ? 'R' : '_');
vga_printch(e.attrib & FA_HIDDEN ? 'H' : '_');
vga_printch(e.attrib & FA_SYSTEM ? 'S' : '_');
vga_printch(e.attrib & FA_LABEL ? 'L' : '_');
vga_printch(e.attrib & FA_DIRECTORY ? 'D' : '_');
vga_printch(e.attrib & FA_ARCHIVE ? 'A' : '_');
vga_printsz(" | ");
u32_dec(e.length, nbuf);
vga_printsz(nbuf);
} }
while (1) halt();
asm ("hlt");
} }

View file

@ -4,6 +4,7 @@
#include "util.h" #include "util.h"
void halt() { void halt() {
vga_printsz("\n\nHalting...");
while (1) while (1)
asm volatile ("hlt"); asm volatile ("hlt");
} }
@ -20,12 +21,12 @@ void panic(uint8_t *message) {
vga_printsz("\n\nStack trace:"); vga_printsz("\n\nStack trace:");
uint8_t stb[6]; uint8_t stb[6];
while (1) { while (1) {
uint32_t ip = *(uint32_t *)(0x38000 + frame + 4); uint32_t ip = *((uint32_t *)frame + 1);
if (!ip) if (!ip)
halt(); halt();
vga_printsz("\n 0x"); vga_printsz("\n 0x");
u16_hex(ip - 0x30000 - 5, stb);//assumes would return to just after a call instruction u16_hex(ip - 0x30000 - 5, stb);//assumes would return to just after a call instruction
vga_printsz(stb); vga_printsz(stb);
frame = *(uint32_t *)(0x38000 + frame); frame = *(uint32_t *)frame;
} }
} }

View file

@ -2,8 +2,15 @@
#include "panic.h" #include "panic.h"
#include <stdbool.h> #include <stdbool.h>
void memcpy(void *from, void *to, uint32_t n) { void memcpy(void *to, void *from, uint32_t n) {
panic("Not implemented (memcpy)."); uint32_t *tp = to, *fp = from;
while (n >= 4) {
*(tp++) = *(fp++);
n -= 4;
}
uint8_t *tpp = (uint8_t *)tp, *fpp = (uint8_t *)fp;
while (n--)
*(tpp++) = *(fpp++);
} }
void u32_dec(uint32_t n, uint8_t *b) { void u32_dec(uint32_t n, uint8_t *b) {

View file

@ -1,6 +1,6 @@
#include <stdint.h> #include <stdint.h>
void memcpy(void *from, void *to, uint32_t n); void memcpy(void *to, void *from, uint32_t n);
void outb(uint16_t port, uint8_t value); void outb(uint16_t port, uint8_t value);
uint8_t inb(uint16_t port); uint8_t inb(uint16_t port);
void outw(uint16_t port, uint16_t value); void outw(uint16_t port, uint16_t value);

View file

@ -1,11 +0,0 @@
extern vga_set_color
extern vga_blank
extern vga_scroll
extern vga_printch
extern vga_printsz
extern vga_printsn
extern vga_printu32
extern vga_printu16
extern vga_printu8
extern vga_printu32h
extern vga_printu8h