start tracking stuff folder

This commit is contained in:
pjht 2019-05-25 10:05:36 -05:00
parent 30e043955b
commit e458c56cf9
24 changed files with 2050 additions and 0 deletions

217
stuff/drivers/i386/ide.c Normal file
View File

@ -0,0 +1,217 @@
#include "../../fs/devfs.h"
#include "../../cpu/i386/ports.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <klog.h>
#define IDE_PRIM_IO 0x1f0
#define IDE_PRIM_CTRL 0x3f6
#define IDE_SEC_IO 0x170
#define IDE_SEC_CTRL 0x376
static uint8_t ident[4][512];
static uint8_t* sect_data=NULL;
static uint32_t last_read_sector=0;
static int last_read_base=0;
static int last_read_slave=0;
static uint8_t* read_sect(int base,int slave,uint32_t lba) {
if (last_read_sector==lba && last_read_base==base && last_read_slave==slave && sect_data) {
return sect_data;
}
port_byte_out(base+6,0xe0|slave<<4|((lba&0xFF000000)>>24));
for (int i=0;i<4;i++) port_byte_in(base+7);
while ((port_byte_in(base+7)&0x80)!=0);
port_byte_out(base+2,1);
port_byte_out(base+3,lba&0xFF);
port_byte_out(base+4,(lba&0xFF00)>>8);
port_byte_out(base+5,(lba&0xFF0000)>>16);
port_byte_out(base+7,0x20);
uint8_t* sect=malloc(sizeof(uint8_t)*512);
while ((port_byte_in(base+7)&0x88)!=0x8);
for (int i=0;i<512;i+=2) {
uint16_t data=port_word_in(base);
sect[i]=data&0xFF;
sect[i+1]=(data&0xFF00)>>8;
}
last_read_sector=lba;
last_read_base=base;
last_read_slave=slave;
// if (sect_data) {
// free(sect_data);
// }
sect_data=sect;
return sect;
}
static void write_sect(int base,int slave,uint32_t lba,uint8_t* sect) {
if (last_read_sector==lba && last_read_base==base && last_read_slave==slave && sect_data) {
sect_data=sect;
}
if (!sect_data) {
last_read_sector=lba;
last_read_base=base;
last_read_slave=slave;
sect_data=sect;
}
port_byte_out(base+6,0xe0|slave<<4|((lba&0xFF000000)>>24));
for (int i=0;i<4;i++) port_byte_in(base+7);
while ((port_byte_in(base+7)&0x80)!=0);
port_byte_out(base+2,1);
port_byte_out(base+3,lba&0xFF);
port_byte_out(base+4,(lba&0xFF00)>>8);
port_byte_out(base+5,(lba&0xFF0000)>>16);
port_byte_out(base+7,0x30);
while ((port_byte_in(base+7)&0x88)!=0x8);
for (int i=0;i<512;i+=2) {
port_word_out(base,sect[i]|(sect[i+1]<<8));
for (int i=0;i<4;i++) port_byte_in(base+7);
}
while ((port_byte_in(base+7)&0x80)!=0);
port_byte_out(base+7,0xE7);
}
static int drv(char* filename,int c,long pos,char wr) {
int base;
int slave;
if (strcmp(filename,"hda")==0) {
base=IDE_PRIM_IO;
slave=0;
}
if (strcmp(filename,"hdb")==0) {
base=IDE_PRIM_IO;
slave=1;
}
if (strcmp(filename,"hdc")==0) {
base=IDE_SEC_IO;
slave=0;
}
if (strcmp(filename,"hdc")==0) {
base=IDE_SEC_IO;
slave=1;
}
if (wr) {
uint32_t lba=pos/512;
int offset=pos%512;
uint8_t* sect=read_sect(base,slave,lba);
sect[offset]=(uint8_t)c;
write_sect(base,slave,lba,sect);
return 1;
} else {
uint32_t lba=pos/512;
int offset=pos%512;
uint8_t* sect=read_sect(base,slave,lba);
uint8_t val=sect[offset];
return val;
}
}
void ide_init() {
if (port_byte_in(IDE_PRIM_IO+7)!=0xFF) {
//Detect primary master
port_byte_out(IDE_PRIM_IO+6,0xe0);
for (int i=0;i<4;i++) port_byte_in(IDE_PRIM_IO+7);
while ((port_byte_in(IDE_PRIM_IO+7)&0x80)!=0);
port_byte_out(IDE_PRIM_IO+2,0);
port_byte_out(IDE_PRIM_IO+3,0);
port_byte_out(IDE_PRIM_IO+4,0);
port_byte_out(IDE_PRIM_IO+5,0);
port_byte_out(IDE_PRIM_IO+7,0xEC);
if (port_byte_in(IDE_PRIM_IO+7)!=0) {
uint8_t io4=port_byte_in(IDE_PRIM_IO+4);
uint8_t io5=port_byte_in(IDE_PRIM_IO+5);
if (io4==0x14&&io5==0xeb) {
klog("INFO","IDE primary master is ATAPI");
}
if (io4==0x3c&&io5==0xc3) {
klog("INFO","IDE primary master is SATA");
}
if (io4==0&&io5==0) {
while ((port_byte_in(IDE_PRIM_IO+7)&0x8)!=0x8);
for (int i=0;i<512;i+=2) {
uint16_t data=port_word_in(IDE_PRIM_IO);
ident[0][i]=data&0xFF;
ident[0][i+1]=(data&0xFF00)>>8;
}
klog("INFO","Found IDE primary master");
port_byte_out(IDE_PRIM_CTRL,port_byte_in(IDE_PRIM_CTRL)|0x2);
devfs_add(drv,"hda");
}
}
//Detect primary slave
port_byte_out(IDE_PRIM_IO+6,0xf0);
for (int i=0;i<4;i++) port_byte_in(IDE_PRIM_IO+7);
while ((port_byte_in(IDE_PRIM_IO+7)&0x80)!=0);
port_byte_out(IDE_PRIM_IO+2,0);
port_byte_out(IDE_PRIM_IO+3,0);
port_byte_out(IDE_PRIM_IO+4,0);
port_byte_out(IDE_PRIM_IO+5,0);
port_byte_out(IDE_PRIM_IO+7,0xEC);
if (port_byte_in(IDE_PRIM_IO+7)!=0) {
uint8_t io4=port_byte_in(IDE_PRIM_IO+4);
uint8_t io5=port_byte_in(IDE_PRIM_IO+5);
if (io4==0x14&&io5==0xeb) {
klog("INFO","IDE primary slave is ATAPI");
}
if (io4==0x3c&&io5==0xc3) {
klog("INFO","IDE primary slave is SATA");
}
if (io4==0&&io5==0) {
while ((port_byte_in(IDE_PRIM_IO+7)&0x8)!=0x8);
for (int i=0;i<512;i+=2) {
uint16_t data=port_word_in(IDE_PRIM_IO);
ident[0][i]=data&0xFF;
ident[0][i+1]=(data&0xFF00)>>8;
}
klog("INFO","Found IDE primary slave");
port_byte_out(IDE_PRIM_CTRL,port_byte_in(0x3f6)|0x2);
devfs_add(drv,"hdb");
}
}
}
// if (port_byte_in(IDE_SEC_IO+7)!=0xFF) {
// //Detect secondary master
// port_byte_out(IDE_SEC_IO+6,0xe0);
// for (int i=0;i<4;i++) port_byte_in(IDE_SEC_IO+7);
// while ((port_byte_in(IDE_SEC_IO+7)&0x80)!=0);
// port_byte_out(IDE_SEC_IO+2,0);
// port_byte_out(IDE_SEC_IO+3,0);
// port_byte_out(IDE_SEC_IO+4,0);
// port_byte_out(IDE_SEC_IO+5,0);
// port_byte_out(IDE_SEC_IO+7,0xEC);
// if (port_byte_in(IDE_SEC_IO+7)!=0) {
// if (port_byte_in(IDE_SEC_IO+5)!=0&&port_byte_in(IDE_SEC_IO+6)!=0) {
// }
// while ((port_byte_in(IDE_SEC_IO+7)&0x8)!=0x8);
// for (int i=0;i<512;i+=2) {
// uint16_t data=port_word_in(IDE_SEC_IO);
// ident[0][i]=data&0xFF;
// ident[0][i+1]=(data&0xFF00)>>8;
// }
// klog("INFO","Found IDE secondary master");
// port_byte_out(IDE_SEC_CTRL,port_byte_in(IDE_SEC_CTRL)|0x2);
// devfs_add(drv,"hdc");
// }
// //Detect secondary slave
// port_byte_out(IDE_SEC_IO+6,0xf0);
// for (int i=0;i<4;i++) port_byte_in(IDE_SEC_IO+7);
// while ((port_byte_in(IDE_SEC_IO+7)&0x80)!=0);
// port_byte_out(IDE_SEC_IO+2,0);
// port_byte_out(IDE_SEC_IO+3,0);
// port_byte_out(IDE_SEC_IO+4,0);
// port_byte_out(IDE_SEC_IO+5,0);
// port_byte_out(IDE_SEC_IO+7,0xEC);
// if (port_byte_in(IDE_SEC_IO+7)!=0) {
// if (port_byte_in(IDE_SEC_IO+5)!=0&&port_byte_in(IDE_SEC_IO+6)!=0) {
// }
// while ((port_byte_in(IDE_SEC_IO+7)&0x8)!=0x8);
// for (int i=0;i<512;i+=2) {
// uint16_t data=port_word_in(IDE_SEC_IO);
// ident[0][i]=data&0xFF;
// ident[0][i+1]=(data&0xFF00)>>8;
// }
// klog("INFO","Found IDE decondaryary slave");
// port_byte_out(IDE_SEC_CTRL,port_byte_in(IDE_SEC_CTRL)|0x2);
// devfs_add(drv,"hdd");
// }
// }
}

104
stuff/drivers/i386/pci.c Normal file
View File

@ -0,0 +1,104 @@
#include <stdint.h>
#include "../../cpu/i386/ports.h"
#include <klog.h>
#include "pci.h"
#include "../vga.h"
#include <stdlib.h>
pci_dev_common_info** pci_devs;
static uint32_t max_devs;
uint32_t pci_num_devs;
static uint32_t read_config(uint8_t bus,uint8_t device,uint8_t func,uint8_t offset) {
uint32_t address;
uint32_t lbus=(uint32_t)bus;
uint32_t ldev=(uint32_t)device;
uint32_t lfunc=(uint32_t)func;
address=(uint32_t)((lbus << 16)|(ldev << 11)|(lfunc<<8)|(offset&0xfc)|((uint32_t)0x80000000));
port_long_out(PCI_CONFIG_ADDRESS,address);
uint32_t data=port_long_in(PCI_CONFIG_DATA);
return data;
}
static void write_config(uint8_t bus,uint8_t device,uint8_t func,uint8_t offset,uint32_t data) {
uint32_t address;
uint32_t lbus=(uint32_t)bus;
uint32_t ldev=(uint32_t)device;
uint32_t lfunc=(uint32_t)func;
address=(uint32_t)((lbus << 16)|(ldev << 11)|(lfunc<<8)|(offset&0xfc)|((uint32_t)0x80000000));
port_long_out(PCI_CONFIG_ADDRESS,address);
port_long_out(PCI_CONFIG_DATA,data);
}
pci_dev_common_info* pci_get_dev_info(uint8_t bus,uint8_t device,uint8_t func) {
uint32_t* info=malloc(sizeof(uint32_t)*5);
info[0]=read_config(bus,device,func,0);
info[1]=read_config(bus,device,func,4);
info[2]=read_config(bus,device,func,8);
info[3]=read_config(bus,device,func,0xC);
pci_dev_common_info* pci_info=(pci_dev_common_info*)info;
pci_info->bus=bus;
pci_info->device=device;
pci_info->func=func;
return pci_info;
}
void pci_set_dev_info(pci_dev_common_info* inf) {
uint32_t* info=(uint32_t*)inf;
write_config(inf->bus,inf->device,inf->func,0,info[0]);
write_config(inf->bus,inf->device,inf->func,4,info[1]);
write_config(inf->bus,inf->device,inf->func,8,info[2]);
write_config(inf->bus,inf->device,inf->func,0xC,info[3]);
}
static void checkFunction(pci_dev_common_info* info);
static void checkDevice(uint8_t bus, uint8_t device) {
pci_dev_common_info* info=pci_get_dev_info(bus,device,0);
if(info->vend_id==0xFFFF||info->class_code==0xFF) {
return;
}
checkFunction(info);
if((info->header_type&0x80)!=0) {
for(uint8_t function=1;function<8;function++) {
pci_dev_common_info* info=pci_get_dev_info(bus,device,function);
if(info->vend_id!=0xFFFF&&info->class_code!=0xFF) {
checkFunction(info);
}
}
}
}
static void checkFunction(pci_dev_common_info* info) {
if (pci_num_devs==max_devs) {
max_devs+=32;
pci_devs=malloc(sizeof(pci_dev_common_info)*max_devs);
}
pci_devs[pci_num_devs]=info;
pci_num_devs++;
klog("INFO","Found PCI device. Class code:%x, Subclass:%x Prog IF:%x",info->class_code,info->subclass,info->prog_if);
klog("INFO","Vendor ID:%x, Device ID:%x",info->vend_id,info->dev_id);
if ((info->header_type&0x7f)==0) {
for (uint8_t offset=0x10;offset<0x10+4*6;offset+=4) {
uint32_t bar=read_config(info->bus,info->device,info->func,offset);
if (bar!=0) {
if (bar&0x1) {
klog("INFO","IO BAR%d:%x",(offset-0x10)/4,bar&0xFFFFFFFC);
} else {
klog("INFO","MEM BAR%d:%x",(offset-0x10)/4,bar&0xFFFFFFF0);
}
}
}
}
}
void pci_init() {
pci_devs=malloc(sizeof(pci_dev_common_info)*32);
max_devs=32;
pci_num_devs=0;
for(uint16_t bus=0;bus<1; bus++) {
for(uint8_t device=0;device<32; device++) {
checkDevice(bus, device);
}
}
}

13
stuff/drivers/i386/pci.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef PCI_INTERN_H
#define PCI_INTERN_H
#include <stdint.h>
#include "../pci.h"
#define PCI_CONFIG_ADDRESS 0xCF8
#define PCI_CONFIG_DATA 0xCFC
pci_dev_common_info* pci_get_dev_info(uint8_t bus,uint8_t device,uint8_t func);
void pci_set_dev_info(pci_dev_common_info* inf);
#endif

159
stuff/drivers/i386/serial.c Normal file
View File

@ -0,0 +1,159 @@
#include "../../cpu/i386/ports.h"
#include "../../cpu/i386/isr.h"
#include "../serial.h"
#include <stdio.h>
#include <string.h>
#include <devbuf.h>
#include "../vga.h"
#include "../../fs/devfs.h"
#include <klog.h>
#include <stdint.h>
#define SERIAL_LINE_ENABLE_DLAB 0x80
static devbuf* bufs[4];
static int data_port(int com) {
switch (com) {
case 0: return 0x3f8;
case 1: return 0x2f8;
case 2: return 0x3e8;
case 3: return 0x2e8;
}
return 0;
}
static int int_port(int com) {
switch (com) {
case 0: return 0x3f9;
case 1: return 0x2f9;
case 2: return 0x3e9;
case 3: return 0x2e9;
}
return 0;
}
static int fifo_port(int com) {
switch (com) {
case 0: return 0x3fa;
case 1: return 0x2fa;
case 2: return 0x3ea;
case 3: return 0x2ea;
}
return 0;
}
static int line_cmd_port(int com) {
switch (com) {
case 0: return 0x3fb;
case 1: return 0x2fb;
case 2: return 0x3eb;
case 3: return 0x2eb;
}
return 0;
}
static int modem_port(int com) {
switch (com) {
case 0: return 0x3fc;
case 1: return 0x2fc;
case 2: return 0x3ec;
case 3: return 0x2ec;
}
return 0;
}
static int line_stat_port(int com) {
switch (com) {
case 0: return 0x3fd;
case 1: return 0x2fd;
case 2: return 0x3ed;
case 3: return 0x2ed;
}
return 0;
}
static int scratch_port(int com) {
switch (com) {
case 0: return 0x3ff;
case 1: return 0x2ff;
case 2: return 0x3ef;
case 3: return 0x2ef;
}
return 0;
}
static void configure_baud_rate(uint32_t divisor,int com) {
port_byte_out(line_cmd_port(com),SERIAL_LINE_ENABLE_DLAB);
port_byte_out(data_port(com),(divisor>>8)&0xFF);
port_byte_out(data_port(com),divisor&0xFF);
}
static int is_transmit_fifo_empty(int com) {
return port_byte_in(line_stat_port(com))&0x20;
}
static void configure(uint32_t com, uint32_t rate) {
configure_baud_rate(115200/rate,com);
port_byte_out(line_cmd_port(com),0x03);
port_byte_out(fifo_port(com),0xC7);
port_byte_out(modem_port(com),0x03);
port_byte_out(int_port(com),0x01);
}
static int drv(char* filename,int c,long pos,char wr) {
int com;
switch (filename[4]) {
case '0':
com=0;
break;
case '1':
com=1;
break;
case '2':
com=2;
break;
case '3':
com=3;
break;
}
if (wr) {
while (!is_transmit_fifo_empty(com)) continue;
port_byte_out(data_port(com),c);
return 0;
} else {
return devbuf_get(bufs[com]);
}
}
void serial_int_handler_1(registers_t regs) {
char data=port_byte_in(data_port(0));
if (data=='\r') {
data='\n';
}
devbuf_add(data,bufs[0]);
}
void serial_int_handler_2(registers_t regs) {
devbuf_add(port_byte_in(data_port(1)),bufs[1]);
}
void serial_init() {
klog("INFO","Scanning for serial ports");
for (int i=0;i<2;i++) {
port_byte_out(scratch_port(i),0xaa);
if (port_byte_in(scratch_port(i))==0xaa) {
klog("INFO","Found COM%d",i+1);
bufs[i]=devbuf_init();
switch (i) {
case 0:
isr_register_handler(IRQ4,serial_int_handler_1);
configure(0,9600);
devfs_add(drv,"ttyS0");
break;
case 1:
isr_register_handler(IRQ3,serial_int_handler_2);
configure(1,9600);
devfs_add(drv,"ttyS1");
}
}
}
}

84
stuff/drivers/i386/vga.c Normal file
View File

@ -0,0 +1,84 @@
#include <grub/text_fb_info.h>
#include "../vga.h"
#include "../../cpu/i386/ports.h"
#include <string.h>
#include <stddef.h>
#define xy_to_indx(x,y) ((x+(y*width))*2)
static char* screen;
static int width;
static int height;
static int x;
static int y;
static vga_colors fg_color;
static vga_colors bg_color;
static void set_char(int x,int y,char c) {
screen[xy_to_indx(x,y)]=c;
screen[xy_to_indx(x,y)+1]=(bg_color<<4)|fg_color;
}
void vga_clear() {
for (int y=0;y<height;y++) {
for (int x=0;x<width;x++) {
set_char(x,y,' ');
}
}
}
static void set_cursor(int x,int y) {
int pos=(x+(y*width));
port_byte_out(0x3D4,0xF);
port_byte_out(0x3D5,pos&0xFF);
port_byte_out(0x3D4,0xE);
port_byte_out(0x3D5,(pos&0xFF00)>>8);
}
void vga_init(text_fb_info framebuffer_info) {
x=0;
y=0;
fg_color=VGA_WHITE;
bg_color=VGA_BLACK;
screen=framebuffer_info.address;
width=framebuffer_info.width;
height=framebuffer_info.height;
port_byte_out(0x3D4,0xA);
port_byte_out(0x3D5,(port_byte_in(0x3D5)&0xC0)|14);
port_byte_out(0x3D4,0xB);
port_byte_out(0x3D5,(port_byte_in(0x3D5)&0xE0)|15);
set_cursor(0,0);
vga_clear();
}
void vga_write_string(const char* string) {
for (size_t i=0;i<strlen(string);i++) {
char c=string[i];
if (c=='\n') {
x=0;
y++;
} else {
set_char(x,y,c);
x++;
}
if (x==width) {
x=0;
y++;
}
if (y==height) {
x=0;
y=0;
// char* pg1=(char*)((uint32_t)screen+0xfa0);
// memcpy(pg1,&screen[xy_to_indx(0,1)],xy_to_indx(0,24));
// vga_clear();
// memcpy(&screen,pg1,xy_to_indx(0,25));
}
}
set_cursor(x,y);
}
void vga_backspace() {
if (x!=0) {
x--;
set_char(x,y,' ');
set_cursor(x,y);
}
}

6
stuff/drivers/ide.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef IDE_H
#define IDE_H
void ide_init();
#endif

6
stuff/drivers/parallel.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef PARALLEL_H
#define PARALLEL_H
void parallel_init();
#endif

49
stuff/drivers/pci.h Normal file
View File

@ -0,0 +1,49 @@
#ifndef PCI_H
#define PCI_H
#include <stdint.h>
typedef struct {
uint16_t vend_id;
uint16_t dev_id;
uint16_t command;
uint16_t status;
uint8_t rev_id;
uint8_t prog_if;
uint8_t subclass;
uint8_t class_code;
uint8_t cache_line_size;
uint8_t lat_timer;
uint8_t header_type;
uint8_t bist;
uint16_t bus;
uint8_t device;
uint8_t func;
} __attribute__((packed)) pci_dev_common_info;
typedef enum {
PCI_CLASS_UNCLASSIFIED=0x0,
PCI_CLASS_STORAGE=0x1,
PCI_CLASS_NETWORK=0x2,
PCI_CLASS_DISPLAY=0x3,
PCI_CLASS_MULTIMEDIA=0x4,
PCI_CLASS_MEMORY=0x5,
PCI_CLASS_BRIDGE=0x6,
PCI_CLASS_SIMPCOM=0x7,
PCI_CLASS_BASEPERIPH=0x8,
PCI_CLASS_INPDEV=0x9,
PCI_CLASS_DOCK=0xa,
PCI_CLASS_CPU=0xb,
PCI_CLASS_SERBUS=0xc,
PCI_CLASS_WIRELESS=0xd,
PCI_CLASS_INTELLIGENT=0xe,
PCI_CLASS_SATELLITE=0xf,
PCI_CLASS_ENCRYPTION=0x10,
PCI_CLASS_SIGPROCESS=0x11,
} pci_class;
extern pci_dev_common_info** pci_devs;
extern uint32_t pci_num_devs;
void pci_init();
#endif

6
stuff/drivers/ps2.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef PS2_EXT_H
#define PS2_EXT_H
void ps2_init();
#endif

7
stuff/drivers/serial.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef SERIAL_H
#define SERIAL_H
#include <stdint.h>
void serial_init();
#endif

7
stuff/drivers/timer.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef TIMER_H
#define TIMER_H
void wait(int milli);
void timer_init();
#endif

29
stuff/drivers/vga.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef vga_H
#define vga_H
typedef enum {
VGA_BLACK=0,
VGA_BLUE=1,
VGA_GREEN=2,
VGA_CYAN=3,
VGA_RED=4,
VGA_PURPLE=5,
VGA_BROWN=6,
VGA_GRAY=7,
VGA_DARK_GRAY=8,
VGA_LIGHT_BLUE=9,
VGA_LIGHT_GREEN=10,
VGA_LIGHT_CYAN=11,
VGA_LIGHT_RED=12,
VGA_LIGHT_PURPLE=13,
VGA_YELLOW=14,
VGA_WHITE=15
} vga_colors;
void vga_init();
void vga_write_string(const char *string);
void vga_clear();
void vga_backspace();
#endif

View File

@ -0,0 +1,84 @@
#include <grub/text_fb_info.h>
#include "../vga.h"
#include "../../cpu/x86_64/ports.h"
#include <string.h>
#include <stddef.h>
#define xy_to_indx(x,y) ((x+(y*width))*2)
static char* screen;
static int width;
static int height;
static int x;
static int y;
static vga_colors fg_color;
static vga_colors bg_color;
static void set_char(int x,int y,char c) {
screen[xy_to_indx(x,y)]=c;
screen[xy_to_indx(x,y)+1]=(bg_color<<4)|fg_color;
}
void vga_clear() {
for (int y=0;y<height;y++) {
for (int x=0;x<width;x++) {
set_char(x,y,' ');
}
}
}
static void set_cursor(int x,int y) {
int pos=(x+(y*width));
port_byte_out(0x3D4,0xF);
port_byte_out(0x3D5,pos&0xFF);
port_byte_out(0x3D4,0xE);
port_byte_out(0x3D5,(pos&0xFF00)>>8);
}
void vga_init(text_fb_info framebuffer_info) {
x=0;
y=0;
fg_color=VGA_WHITE;
bg_color=VGA_BLACK;
screen=framebuffer_info.address;
width=framebuffer_info.width;
height=framebuffer_info.height;
port_byte_out(0x3D4,0xA);
port_byte_out(0x3D5,(port_byte_in(0x3D5)&0xC0)|14);
port_byte_out(0x3D4,0xB);
port_byte_out(0x3D5,(port_byte_in(0x3D5)&0xE0)|15);
set_cursor(0,0);
vga_clear();
}
void vga_write_string(const char* string) {
for (size_t i=0;i<strlen(string);i++) {
char c=string[i];
if (c=='\n') {
x=0;
y++;
} else {
set_char(x,y,c);
x++;
}
if (x==width) {
x=0;
y++;
}
if (y==height) {
x=0;
y=0;
// char* pg1=(char*)((uint32_t)screen+0xfa0);
// memcpy(pg1,&screen[xy_to_indx(0,1)],xy_to_indx(0,24));
// vga_clear();
// memcpy(&screen,pg1,xy_to_indx(0,25));
}
}
set_cursor(x,y);
}
void vga_backspace() {
if (x!=0) {
x--;
set_char(x,y,' ');
set_cursor(x,y);
}
}

71
stuff/fs/devfs.c Normal file
View File

@ -0,0 +1,71 @@
#include "../..//vfs.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "devfs.h"
static char** devices;
static dev_drv* dev_drivers;
static uint32_t num_devices;
static uint32_t max_devices;
char devfs_drv(fs_op op,FILE* stream,void* data1,void* data2) {
if (op==FSOP_MOUNT) {
return 1;
}
if (op==FSOP_OPEN) {
for (uint32_t i=0;i<num_devices;i++) {
if (strcmp(devices[i],stream->path)==0) {
return 1;
}
}
return 0;
}
if (op==FSOP_GETC) {
uint32_t i;
for (i=0;i<num_devices;i++) {
if (strcmp(devices[i],stream->path)==0) {
break;
}
}
*((int*)data1)=dev_drivers[i]((char*)stream->path,0,stream->pos,0);
stream->pos+=1;
return 1;
}
if (op==FSOP_PUTC) {
uint32_t i;
for (i=0;i<num_devices;i++) {
if (strcmp(devices[i],stream->path)==0) {
break;
}
}
dev_drivers[i]((char*)stream->path,*((int*)data1),stream->pos,1);
stream->pos+=1;
return 1;
}
if (op==FSOP_CLOSE) {
return 1;
}
return 0;
}
void init_devfs() {
devices=malloc(sizeof(char*)*32);
dev_drivers=malloc(sizeof(dev_drv)*32);
num_devices=0;
max_devices=32;
register_fs(devfs_drv,"devfs");
mount("/dev/","","devfs");
}
void devfs_add(dev_drv drv,char* name) {
if (num_devices==max_devices) {
devices=realloc(devices,sizeof(char*)*(max_devices+32));
dev_drivers=realloc(dev_drivers,sizeof(dev_drv)*(max_devices+32));
max_devices+=32;
}
dev_drivers[num_devices]=drv;
devices[num_devices]=malloc(sizeof(char)*(strlen(name)+1));
strcpy(devices[num_devices],name);
num_devices++;
}

9
stuff/fs/devfs.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef DEVFS_H
#define DEVFS_H
typedef int (*dev_drv)(char* filename,int c,long pos,char wr);
void init_devfs();
void devfs_add(dev_drv drv,char* name);
#endif

479
stuff/fs/ext2.c Normal file
View File

@ -0,0 +1,479 @@
#include "../..//vfs.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdint.h>
#include <errno.h>
#include <klog.h>
#include "ext2_structs.h"
ext2_superblock* supblks;
uint32_t* blk_size;
blk_grp** blk_grps;
uint32_t* blk_grp_num;
char** mnts;
char** devs;
int num_mnts;
int max_mnts;
typedef struct {
uint32_t inode;
char type;
char* name;
} dir_entry;
typedef struct {
int num;
inode* inode;
char is_cont_valid;
char* contents;
} file_info;
static char get_bmap_bit(uint32_t index,uint8_t* bitmap) {
uint32_t byte=index/8;
uint32_t bit=index%8;
char entry=bitmap[byte];
return (entry&(1<<bit))>0;
}
static void set_bmap_bit(uint32_t index,uint8_t* bitmap) {
uint32_t byte=index/8;
uint32_t bit=index%8;
bitmap[byte]=bitmap[byte]|(1<<bit);
}
void* read_blk(int blknum,FILE* f,int num) {
void* block=malloc(sizeof(uint8_t)*blk_size[num]);
fseek(f,blknum*blk_size[num],SEEK_SET);
fread(block,1,sizeof(uint8_t)*blk_size[num],f);
return block;
}
void write_blk(int blknum,void* block,FILE* f,int num) {
fseek(f,blknum*blk_size[num],SEEK_SET);
fwrite(block,1,sizeof(uint8_t)*blk_size[num],f);
}
inode* read_inode(uint32_t inode_num,FILE* f,int num) {
ext2_superblock supblk=supblks[num];
uint32_t grp=(inode_num-1)/supblk.s_inodes_per_group;
uint32_t index=(inode_num-1)%supblk.s_inodes_per_group;
uint32_t starting_blk=blk_grps[num][grp].bg_inode_table;
size_t inodes_per_blk=blk_size[num]/sizeof(inode);
uint32_t blk=starting_blk+(index/inodes_per_blk);
uint32_t offset=index%inodes_per_blk;
inode* inodes=read_blk(blk,f,num);
return &inodes[offset];
}
void write_inode(uint32_t inode_num,inode* node,FILE* f,int num) {
ext2_superblock supblk=supblks[num];
uint32_t grp=(inode_num-1)/supblk.s_inodes_per_group;
uint32_t index=(inode_num-1)%supblk.s_inodes_per_group;
uint32_t starting_blk=blk_grps[num][grp].bg_inode_table;
size_t inodes_per_blk=blk_size[num]/sizeof(inode);
uint32_t blk=starting_blk+(index/inodes_per_blk);
uint32_t offset=index%inodes_per_blk;
inode* inodes=read_blk(blk,f,num);
inodes[offset]=*node;
write_blk(blk,inodes,f,num);
}
uint32_t reserve_inode(FILE* f,int num) {
blk_grp* grps=blk_grps[num];
for (uint32_t i=0;i<blk_grp_num[num];i++) {
if (grps[i].bg_free_inodes_count==0) {
continue;
}
uint32_t starting_blk=grps[i].bg_inode_bitmap;
uint32_t num_blks=((supblks[num].s_inodes_per_group/8)/blk_size[num])+1;
uint8_t* bitmap=malloc(sizeof(uint8_t)*num_blks*blk_size[num]);
for (uint32_t i=0;i<num_blks;i++) {
memcpy(&bitmap[i*blk_size[num]],read_blk(i+starting_blk,f,num),blk_size[num]);
}
uint32_t j;
for (j=0;j<supblks[num].s_inodes_per_group;j++) {
if (get_bmap_bit(j,bitmap)==0) break;
}
set_bmap_bit(j,bitmap);
if (get_bmap_bit(j,bitmap)==0) {
klog("INFO","Could not reserve inode!");
for (;;);
} else {
klog("INFO","Inode reserved");
}
for (uint32_t i=0;i<num_blks;i++) {
write_blk(i+starting_blk,&bitmap[i*blk_size[num]],f,num);
}
return (256*i)+j;
}
return 0;
}
uint64_t get_sz(inode* node,int num) {
uint64_t size=node->i_size;
if (supblks[num].s_feature_rw_compat&EXT2_FEATURE_RW_COMPAT_LARGE_FILE) {
size=size|(((uint64_t)node->i_ext_size_or_dir_acl)<<32);
}
return size;
}
void set_sz(inode* node,uint64_t sz,int num) {
if (supblks[num].s_feature_rw_compat&EXT2_FEATURE_RW_COMPAT_LARGE_FILE) {
node->i_size=(uint32_t)(sz&0xFFFFFFFF);
node->i_ext_size_or_dir_acl=(uint32_t)((sz&0xFFFFFFFF00000000)>>32);
} else {
node->i_size=(uint32_t)sz;
}
}
void inc_sz(inode* node,int num) {
if (supblks[num].s_feature_rw_compat&EXT2_FEATURE_RW_COMPAT_LARGE_FILE) {
node->i_size+=1;
if (node->i_size==0) {
node->i_ext_size_or_dir_acl+=1;
}
} else {
node->i_size+=1;
}
}
int read_char(inode* node,FILE* f,int pos,int num) {
if (node->i_block[0]==0) {
return -1;
}
int block=pos/blk_size[num];
pos=pos%blk_size[num];
if (block<12) {
if (node->i_block[block]==0) {
return -1;
} else {
return ((char*)read_blk(node->i_block[block],f,num))[pos];
}
} else if (block<268) {
uint32_t* blocks=read_blk(node->i_block[12],f,num);
if (blocks[block-12]==0) {
return -1;
} else {
return ((char*)read_blk(blocks[block],f,num))[pos];
}
}
return -1;
}
void append_char(inode* node,uint32_t inode_num,uint8_t c,FILE* f,int num) {
uint64_t size=get_sz(node,num);
uint32_t blk_idx=size/blk_size[num];
uint32_t offset=size%blk_size[num];
if (blk_idx>12||(node->i_block[blk_idx]==0)) return;
uint32_t blk=node->i_block[blk_idx];
uint8_t* block=read_blk(blk,f,num);
block[offset]=c;
write_blk(blk,block,f,num);
inc_sz(node,num);
write_inode(inode_num,node,f,num);
}
int write_char(inode* node,uint8_t c,uint64_t pos,FILE* f,int num) {
uint64_t size=get_sz(node,num);
uint32_t blk_idx=pos/blk_size[num];
if (pos>size) {
if (blk_idx>12) {
return EFBIG;
} else {
if (node->i_block[blk_idx]==0) {
for (uint32_t i=0;i<=blk_idx;i++) {
// node.i_block[blk_idx]=reserve_block(f,num);
return 0;
}
} else {
set_sz(node,size++,num);
}
}
}
uint32_t offset=pos%blk_size[num];
if (blk_idx>12||(node->i_block[blk_idx]==0)) return 0;
uint32_t blk=node->i_block[blk_idx];
uint8_t* block=read_blk(blk,f,num);
block[offset]=c;
write_blk(blk,block,f,num);
return 0;
}
void* read_inode_contents(inode* node,FILE* f,int num) {
if (node->i_block[0]==0) {
return NULL;
}
uint64_t size=get_sz(node,num);
char* data=malloc(sizeof(char)*ceil(size/blk_size[num]));
for (int i=0;i<12;i++) {
if (node->i_block[i]==0) {
break;
}
memcpy(&data[i*blk_size[num]],read_blk(node->i_block[i],f,num),blk_size[num]);
}
if (node->i_block[12]!=0) {
uint32_t* blocks=read_blk(node->i_block[12],f,num);
for (int i=0;i<256;i++) {
if (blocks[i]==0) {
break;
}
memcpy(&data[(i+12)*blk_size[num]],read_blk(blocks[i],f,num),blk_size[num]);
}
}
return (void*)data;
}
dir_entry* get_dir_listing(uint32_t inode_num,FILE* f,int num) {
dir_entry* entries=malloc(sizeof(dir_entry)*100);
int num_entries_used=0;
int max_len=100;
inode* dir_inode=read_inode(inode_num,f,num);
uint32_t size=dir_inode->i_size;
uint32_t tot_size=0;
ext2_dir_entry* dir=read_inode_contents(dir_inode,f,num);
ext2_dir_entry* current_entry=dir;
for(int i=0;tot_size<size;i++) {
if (current_entry->file_type==0) {
break;
}
if(num_entries_used==max_len) {
max_len+=100;
entries=realloc(entries,sizeof(dir_entry)*max_len);
}
entries[num_entries_used].inode=current_entry->inode;
entries[num_entries_used].type=current_entry->file_type;
// entries[num_entries_used].name=malloc(sizeof(char)*((current_entry->name_len)+1));
entries[num_entries_used].name=current_entry->file_name;
// strcpy(entries[num_entries_used].name,current_entry->file_name);
entries[num_entries_used].name[(int)current_entry->name_len]='\0';
num_entries_used++;
tot_size+=current_entry->rec_len;
current_entry=(ext2_dir_entry*)(((char*)current_entry)+current_entry->rec_len);
}
if(num_entries_used==max_len) {
max_len+=1;
entries=realloc(entries,sizeof(dir_entry)*max_len);
}
entries[num_entries_used].inode=0;
return entries;
}
void free_dir_listing(char** names) {
// for(int i=0;names[i]!=NULL;i++) {
// free(names[i]);
// }
// free(names);
}
ext2_dir_entry* read_dir_entry(uint32_t inode_num,uint32_t dir_entry_num,FILE* f,int num) {
inode* dir_inode=read_inode(inode_num,f,num);
uint32_t size=dir_inode->i_size;
uint32_t tot_size=0;
uint32_t ent_num=0;
ext2_dir_entry* dir=read_inode_contents(dir_inode,f,num);
ext2_dir_entry* current_entry=dir;
for(int i=0;tot_size<size;i++) {
if (current_entry->file_type==0) {
break;
}
if(ent_num==dir_entry_num) {
return current_entry;
}
ent_num++;
tot_size+=current_entry->rec_len;
current_entry=(ext2_dir_entry*)(((char*)current_entry)+current_entry->rec_len);
}
return NULL;
}
uint32_t inode_for_fname(uint32_t dir_inode_num, char* name, char* got_inode,FILE* f,int num) {
*got_inode=0;
dir_entry* entries=get_dir_listing(dir_inode_num,f,num);
for(int i=0;entries[i].inode!=0;i++) {
if (strcmp(entries[i].name,name)==0) {
*got_inode=1;
return entries[i].inode;
}
}
return 0;
}
char* fname_for_inode(uint32_t dir_inode_num, uint32_t inode_num,FILE* f,int num) {
for(int i=0;;i++) {
ext2_dir_entry* entry=read_dir_entry(dir_inode_num,i,f,num);
if (entry) {
if (entry->inode==inode_num) {
char* name=malloc(strlen(entry->file_name)+1);
strcpy(name,entry->file_name);
return name;
}
} else {
break;
}
}
return NULL;
}
static char drv(fs_op op,FILE* stream,void* data1,void* data2) {
if (op==FSOP_MOUNT) {
char* dev=(char*)data2;
if (max_mnts==num_mnts) {
supblks=realloc(supblks,sizeof(ext2_superblock)*(max_mnts+32));
blk_size=realloc(blk_size,sizeof(uint32_t)*(max_mnts+32));
blk_grps=realloc(blk_grps,sizeof(blk_grp*)*(max_mnts+32));
blk_grp_num=realloc(blk_grp_num,sizeof(uint32_t)*(max_mnts+32));
mnts=realloc(mnts,sizeof(char*)*(max_mnts+32));
devs=realloc(devs,sizeof(char*)*(max_mnts+32));
max_mnts+=32;
}
FILE* f=fopen(dev,"r");
fseek(f,1024,SEEK_SET);
ext2_superblock* supblk=(ext2_superblock*)malloc(sizeof(char)*1024);
fread(supblk,1024,1,f);
supblks[num_mnts]=*supblk;
blk_size[num_mnts]=1024<<(supblk->s_log_blk_size);
double num_blk_grps_dbl=supblk->s_blocks_count/(double)supblk->s_blocks_per_group;
uint32_t num_blk_grps=ceil(num_blk_grps_dbl);
uint32_t num_blks=((sizeof(blk_grp)*num_blk_grps)/blk_size[num_mnts])+1;
blk_grps[num_mnts]=malloc(sizeof(uint8_t)*num_blks*1024);
blk_grp_num[num_mnts]=num_blk_grps;
char* data_ptr=(char*)(blk_grps[num_mnts]);
for (uint32_t i=0;i<num_blks;i++) {
memcpy(&data_ptr[i*blk_size[num_mnts]],read_blk(i+2,f,num_mnts),blk_size[num_mnts]);
}
fclose(f);
mnts[num_mnts]=(char*)data1;
devs[num_mnts]=dev;
num_mnts++;
return 1;
}
if (op==FSOP_OPEN) {
file_info* data=NULL;
for (int i=0;i<num_mnts;i++) {
if (strcmp(mnts[i],stream->mntpnt)==0) {
stream->data=malloc(sizeof(file_info));
data=stream->data;
data->num=i;
data->is_cont_valid=0;
break;
}
}
if (data) {
FILE* f=fopen(devs[data->num],"r+");
uint32_t inode_num=2;
inode* node;
for (char* tok=strtok(stream->path,"/");tok!=NULL;tok=strtok(NULL,"/")) {
char got_inode;
uint32_t temp_num=inode_for_fname(inode_num,tok,&got_inode,f,data->num);
if (got_inode) {
inode_num=temp_num;
node=read_inode(inode_num,f,data->num);
if ((node->i_mode&EXT2_S_IFDIR)==0) {
char* next_tok=strtok(NULL,"/");
if (next_tok) {
errno=ENOTDIR;
fclose(f);
return 0;
} else {
break;
}
}
} else {
if (stream->wr) {
char* next_tok=strtok(NULL,"/");
if (next_tok) {
errno=ENOENT;
fclose(f);
return 0;
} else {
klog("INFO","Creating new file");
klog("INFO","Parent directory inode:%d",inode_num);
inode_num=reserve_inode(f,data->num);
klog("INFO","Inode %d is free",inode_num);
inode node;
node.i_mode=EXT2_S_IFREG;
node.i_uid=0;
node.i_size=0;
node.i_atime=0;
node.i_ctime=0;
node.i_mtime=0;
node.i_dtime=0;
node.i_gid=0;
node.i_links_count=1;
node.i_blocks=0;
node.i_flags=0;
node.i_osd1=0;
for (int i=0;i<15;i++) {
node.i_block[i]=0;
}
node.i_generation=0;
node.i_file_acl=0;
node.i_ext_size_or_dir_acl=0;
node.i_faddr=0;
node.i_osd2=0;
write_inode(inode_num,&node,f,data->num);
errno=ENOENT;
fclose(f);
return 0;
}
}
errno=ENOENT;
fclose(f);
return 0;
}
}
data->inode=node;
fclose(f);
return 1;
} else {
return 0;
}
}
if (op==FSOP_GETC) {
file_info* data=stream->data;
//char* contents;
// if (data->is_cont_valid) {
// contents=data->contents;
// } else {
// FILE* f=fopen(devs[data->num],"r");
// contents=read_inode_contents(data->inode,f,data->num);
// fclose(f);
// data->is_cont_valid=1;
// data->contents=contents;
// }
if (stream->pos>get_sz(data->inode,data->num)) {
*((int*)data1)=EOF;
stream->eof=1;
return 1;
}
FILE* f=fopen(devs[data->num],"r");
*((int*)data1)=read_char(data->inode,f,stream->pos,data->num);
fclose(f);
stream->pos++;
return 1;
}
if (op==FSOP_PUTC) {
file_info* data=stream->data;
FILE* f=fopen(devs[data->num],"r+");
write_char(data->inode,*((uint8_t*)data1),stream->pos,f,data->num);
return 1;
}
if (op==FSOP_CLOSE) {
return 1;
}
return 0;
}
void init_ext2() {
supblks=malloc(sizeof(ext2_superblock)*32);
blk_size=malloc(sizeof(uint32_t)*32);
blk_grps=malloc(sizeof(blk_grp*)*32);
blk_grp_num=malloc(sizeof(uint32_t)*32);
mnts=malloc(sizeof(char*)*32);
devs=malloc(sizeof(char*)*32);
num_mnts=0;
max_mnts=32;
register_fs(drv,"ext2");
}

6
stuff/fs/ext2.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef EXT2_H
#define EXT2_H
void init_ext2();
#endif

138
stuff/fs/ext2_structs.h Normal file
View File

@ -0,0 +1,138 @@
#ifndef EXT2_STRUCTS_H
#define EXT2_STRUCTS_H
typedef struct {
uint32_t s_inodes_count;
uint32_t s_blocks_count;
uint32_t s_r_blocks_count;
uint32_t s_free_blocks_count;
uint32_t s_free_inodes_count;
uint32_t s_first_data_block;
uint32_t s_log_blk_size;
uint32_t s_log_frag_size;
uint32_t s_blocks_per_group;
uint32_t s_frags_per_group;
uint32_t s_inodes_per_group;
uint32_t s_mtime;
uint32_t s_wtime;
uint16_t s_mnt_count;
uint16_t s_max_mnt_count;
uint16_t s_magic;
uint16_t s_state;
uint16_t s_errors;
uint16_t s_minor_rev_level;
uint32_t s_lastcheck;
uint32_t s_checkinterval;
uint32_t s_creator_os;
uint32_t s_rev_level;
uint16_t s_def_resuid;
uint16_t s_def_resgid;
uint32_t s_first_ino;
uint16_t s_inode_size;
uint16_t s_block_group_nr;
uint32_t s_feature_compat;
uint32_t s_feature_incompat;
uint32_t s_feature_rw_compat;
char s_uuid[16];
char s_volume_name[16];
char s_last_mounted[64];
uint32_t s_algo_bitmap;
char s_prealloc_blocks;
char s_prealloc_dir_blocks;
char s_journal_uuid[16];
uint32_t s_journal_inum;
uint32_t s_journal_dev;
uint32_t s_last_orphan;
} __attribute__((packed)) ext2_superblock;
typedef enum {
EXT2_FEATURE_COMPAT_DIR_PREALLOC=1,
EXT2_FEATURE_COMPAT_IMAGIC_INODES=2,
EXT2_FEATURE_COMPAT_HAS_JOURNAL=4,
EXT2_FEATURE_COMPAT_EXT_ATTR=8,
EXT2_FEATURE_COMPAT_RESIZE_INO=16,
EXT2_FEATURE_COMPAT_DIR_INDEX=32
} s_feature_compat;
typedef enum {
EXT2_FEATURE_INCOMPAT_COMPRESSION=1,
EXT2_FEATURE_INCOMPAT_FILETYPE=2,
EXT2_FEATURE_INCOMPAT_RECOVER=4,
EXT2_FEATURE_INCOMPAT_JOURNAL_DEV=8
} s_feature_incompat;
typedef enum {
EXT2_FEATURE_RW_COMPAT_SPARSE_SUPER=1,
EXT2_FEATURE_RW_COMPAT_LARGE_FILE=2,
EXT2_FEATURE_RW_COMPAT_BTREE_DIR=4
} s_feature_ro_compat;
typedef struct {
uint32_t bg_blk_bitmap;
uint32_t bg_inode_bitmap;
uint32_t bg_inode_table;
uint16_t bg_free_blocks_count;
uint16_t bg_free_inodes_count;
uint16_t bg_used_dirs_count;
char unused[14];
} __attribute__((packed)) blk_grp;
typedef struct {
uint16_t i_mode;
uint16_t i_uid;
uint32_t i_size;
uint32_t i_atime;
uint32_t i_ctime;
uint32_t i_mtime;
uint32_t i_dtime;
uint16_t i_gid;
uint16_t i_links_count;
uint32_t i_blocks;
uint32_t i_flags;
uint32_t i_osd1;
uint32_t i_block[15];
uint32_t i_generation;
uint32_t i_file_acl;
uint32_t i_ext_size_or_dir_acl;
uint32_t i_faddr;
uint32_t i_osd2;
char unused[8];
} __attribute__((packed)) inode;
typedef enum {
EXT2_S_IFIFO=0x100,
EXT2_S_IFCHR=0x2000,
EXT2_S_IFDIR=0x4000,
EXT2_S_IFBLK=0x6000,
EXT2_S_IFREG=0x8000,
EXT2_S_IFLNK=0xA000,
EXT2_S_IFSOCK=0xC000
} i_mode;
typedef enum {
EXT2_SECRM_FL=0x1,
EXT2_UNRM_FL=0x2,
EXT2_COMPR_FL=0x4,
EXT2_SYNC_FL=0x8,
EXT2_IMMUTABLE_FL=0x10,
EXT2_APPEND_FL=0x20,
EXT2_NODUMP_FL=0x40,
EXT2_NOATIME_FL=0x80,
EXT2_DIRTY_FL=0x100,
EXT2_COMPRBLK_FL=0x200,
EXT2_NOCOMPR_FL=0x400,
EXT2_ECOMPR_FL=0x800,
EXT2_BTREE_FL=0x1000,
EXT2_INDEX_FL=0x1000,
EXT2_IMAGIC_FL=0x2000,
EXT2_JOURNAL_DATA_FL=0x4000,
EXT2_RESERVED_FL=0x80000000
} i_flags;
typedef struct {
uint32_t inode;
uint16_t rec_len;
char name_len;
char file_type;
char file_name[1];
} __attribute__((packed)) ext2_dir_entry;
#endif

85
stuff/fs/initrd.c Normal file
View File

@ -0,0 +1,85 @@
#include "../..//vfs.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <klog.h>
static char** names;
static uint32_t* offsets;
static unsigned long* sizes;
static uint32_t num_files;
static FILE* initrd_fd;
static char drv(fs_op op,FILE* stream,void* data1,void* data2) {
if (op==FSOP_MOUNT) {
return 1;
}
if (op==FSOP_OPEN) {
char file_exists=0;
for (uint32_t i=0;i<num_files;i++) {
if (strcmp(names[i],stream->path)==0) {
file_exists=1;
}
}
return file_exists;
}
if (op==FSOP_GETC) {
uint32_t i;
for (i=0;i<num_files;i++) {
if (strcmp(names[i],stream->path)==0) {
break;
}
}
if (stream->pos>=sizes[i]) {
*((int*)data1)=EOF;
stream->eof=1;
return 1;
}
fseek(initrd_fd,offsets[i]+stream->pos,SEEK_SET);
*((int*)data1)=fgetc(initrd_fd);
stream->pos+=1;
return 1;
}
if (op==FSOP_CLOSE) {
return 1;
}
return 0;
}
void initrd_init() {
initrd_fd=fopen("/dev/initrd","r");
if (!initrd_fd) {
klog("PANIC","Cannot open initrd!");
for(;;) {}
}
uint32_t max_files=32;
num_files=0;
names=malloc(sizeof(char*)*32);
offsets=malloc(sizeof(uint32_t)*32);
sizes=malloc(sizeof(long)*32);
for (uint32_t i=0;i<1;i++) {
if (i==max_files) {
names=realloc(names,sizeof(char*)*(max_files+32));
offsets=realloc(offsets,sizeof(uint32_t)*(max_files+32));
sizes=realloc(sizes,sizeof(long)*(max_files+32));
max_files+=32;
}
uint32_t name_size;
fread(&name_size,4,1,initrd_fd);
if (name_size==0) {
break;
}
char* name=malloc(sizeof(char)*(name_size+1));
fread(name,1,name_size+1,initrd_fd);
long contents_size;
fread(&contents_size,4,1,initrd_fd);
long datapos=ftell(initrd_fd);
fseek(initrd_fd,contents_size,SEEK_CUR);
names[i]=name;
offsets[i]=datapos;
sizes[i]=contents_size;
num_files++;
}
fseek(initrd_fd,0,SEEK_SET);
register_fs(drv,"initrd");
}

6
stuff/fs/initrd.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef INITRD_H
#define INITRD_H
uint32_t initrd_init();
#endif

101
stuff/parts.c Normal file
View File

@ -0,0 +1,101 @@
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <klog.h>
#include "../fs/devfs.h"
typedef struct {
char bootable;
char chs_start[3];
char fs_id;
char chs_end[3];
uint32_t start_lba;
uint32_t length;
} partition;
static const char** part_devs=NULL;
static partition** parts=NULL;
static uint32_t num_part_devs=0;
static uint32_t max_part_devs=0;
int drv(char* filename,int c,long pos,char wr) {
int part_no;
switch (filename[strlen(filename)-1]) {
case '1':
part_no=0;
break;
case '2':
part_no=1;
break;
case '3':
part_no=2;
break;
case '4':
part_no=3;
break;
}
char* str=malloc(sizeof(char)*(strlen(filename)+1));
strcpy(str,filename);
str[strlen(str)-1]='\0';
uint32_t i;
for (i=0;i<num_part_devs;i++) {
if (strcmp(part_devs[i]+5,str)==0) {
break;
}
}
free(str);
uint32_t lba=pos/512;
int offset=pos%512;
if (lba>parts[i][part_no].length) {
klog("INFO","Outside partition boundary");
for(;;);
return 0;
}
lba+=parts[i][part_no].start_lba;
pos=lba*512;
pos+=offset;
if (wr) {
FILE* f=fopen(part_devs[i],"w");
fseek(f,pos,SEEK_SET);
fputc(c,f);
fclose(f);
return 1;
} else {
FILE* f=fopen(part_devs[i],"r");
fseek(f,pos,SEEK_SET);
int c=fgetc(f);
fclose(f);
return c;
}
return 0;
}
void load_parts(const char* path) {
if (num_part_devs==max_part_devs) {
max_part_devs+=32;
part_devs=realloc(part_devs,sizeof(char*)*max_part_devs);
parts=realloc(parts,sizeof(partition*)*num_part_devs);
}
FILE* f=fopen(path,"r");
part_devs[num_part_devs]=path;
path+=5;
parts[num_part_devs]=malloc(sizeof(partition)*4);
fseek(f,0x1BE,SEEK_SET);
fread(parts[num_part_devs],sizeof(partition),4,f);
for (int i=0;i<4;i++) {
if (parts[num_part_devs][i].fs_id!=0) {
klog("INFO","Found partition %d of type %x on sectors %d-%d ",i,(uint8_t)parts[num_part_devs][i].fs_id,parts[num_part_devs][i].start_lba,parts[num_part_devs][i].start_lba+parts[num_part_devs][i].length);
char str[2];
int_to_ascii(i+1,str);
char* part_path=malloc(sizeof(char)*strlen(path)+2);
memcpy(part_path,path,strlen(path));
memcpy(part_path+strlen(path),str,2);
klog("INFO","Path:%s",part_path);
devfs_add(drv,part_path);
}
}
fclose(f);
num_part_devs++;
}

6
stuff/parts.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef PARTS_H
#define PARTS_H
void load_parts(const char* path);
#endif

357
stuff/vfs.c Normal file
View File

@ -0,0 +1,357 @@
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "vfs.h"
typedef struct _vfs_mapping_struct {
char* mntpnt;
uint32_t type;
struct _vfs_mapping_struct* next;
} vfs_mapping;
static const char** drv_names;
static fs_drv* drvs;
static uint32_t max_drvs;
static uint32_t next_drv_indx;
static vfs_mapping* head_mapping;
static vfs_mapping* tail_mapping;
FILE* stdin=NULL;
FILE* stdout=NULL;
FILE* stderr=NULL;
static int vfsstrcmp(const char* s1,const char* s2) {
int i;
for (i = 0; s1[i] == s2[i]; i++) {
if (s1[i] == '\0') return 0;
}
if (s1[i] == '\0') return 0;
return s1[i] - s2[i];
}
void init_vfs() {
drvs=malloc(sizeof(fs_drv)*32);
drv_names=malloc(sizeof(const char**)*32);
max_drvs=32;
next_drv_indx=0;
head_mapping=NULL;
tail_mapping=NULL;
}
uint32_t register_fs(fs_drv drv,const char* type) {
if (next_drv_indx==max_drvs) {
drvs=realloc(drvs,sizeof(fs_drv)*(max_drvs+32));
drv_names=realloc(drv_names,sizeof(char*)*(max_drvs+32));
max_drvs+=32;
}
drvs[next_drv_indx]=drv;
drv_names[next_drv_indx]=type;
next_drv_indx++;
return next_drv_indx-1;
}
char mount(char* mntpnt,char* dev,char* type) {
uint32_t i;
for (i=0;i<next_drv_indx;i++) {
const char* name=drv_names[i];
if (strcmp(name,type)==0) {
break;
}
}
char ok=drvs[i](FSOP_MOUNT,NULL,mntpnt,dev);
if (ok) {
if (head_mapping==NULL) {
vfs_mapping* mapping=malloc(sizeof(vfs_mapping));
mapping->mntpnt=malloc(sizeof(char)*(strlen(mntpnt)+1));
strcpy(mapping->mntpnt,mntpnt);
mapping->type=i;
mapping->next=NULL;
head_mapping=mapping;
tail_mapping=mapping;
} else {
vfs_mapping* mapping=malloc(sizeof(vfs_mapping));
mapping->mntpnt=malloc(sizeof(char)*(strlen(mntpnt)+1));
strcpy(mapping->mntpnt,mntpnt);
mapping->type=i;
mapping->next=NULL;
tail_mapping->next=mapping;
}
return 1;
} else {
return 0;
}
}
FILE* fopen(const char* filename,const char* mode) {
vfs_mapping* mnt=head_mapping;
vfs_mapping* mntpnt=NULL;
const char* path;
uint32_t mntpnt_len=0;
for (;mnt!=NULL;mnt=mnt->next) {
char* root=mnt->mntpnt;
if (strlen(root)>mntpnt_len) {
if (vfsstrcmp(root,filename)==0) {
mntpnt=mnt;
mntpnt_len=strlen(root);
}
}
}
if (mntpnt) {
path=filename+mntpnt_len;
FILE* stream=malloc(sizeof(FILE));
stream->mntpnt=mntpnt->mntpnt;
stream->path=path;
if (strcmp(mode,"w")==0) {
stream->wr=1;
stream->rd=0;
} else if (strcmp(mode,"r+")==0) {
stream->wr=1;
stream->rd=1;
} else {
stream->wr=0;
stream->rd=1;
}
stream->type=mntpnt->type;
stream->pos=0;
stream->eof=0;
stream->error=0;
char ok=drvs[mntpnt->type](FSOP_OPEN,stream,NULL,NULL);
if (ok) {
return stream;
} else {
free(stream);
return NULL;
}
}
return NULL;
}
int fgetc(FILE* stream) {
if (!stream->rd) {
errno=EBADF;
stream->error=1;
return EOF;
}
int c;
drvs[stream->type](FSOP_GETC,stream,&c,NULL);
return c;
}
int getc() {
return fgetc(stdin);
}
char* fgets(char* str,int count,FILE* stream) {
if (!stream->rd) {
errno=EBADF;
stream->error=1;
return NULL;
}
int i;
for (i=0;i<count-1;i++) {
char c=fgetc(stream);
if (c==EOF) {
return NULL;
} else if (c=='\n') {
str[i]=c;
i++;
break;
}
str[i]=c;
}
str[i]='\0';
return str;
}
size_t fread(void* buffer_ptr,size_t size,size_t count,FILE* stream) {
if (!stream->rd) {
errno=EBADF;
stream->error=1;
return 0;
}
char* buffer=(char*)buffer_ptr;
size_t bytes=size*count;
for (size_t i=0;i<bytes;i++) {
int c=fgetc(stream);
if (c==EOF) {
return (size_t)(i/size);
}
buffer[i]=c;
}
return count;
}
int fputc(int c,FILE* stream) {
if (!stream->wr) {
errno=EBADF;
stream->error=1;
return EOF;
}
char ok=drvs[stream->type](FSOP_PUTC,stream,&c,NULL);
if (ok) {
return c;
} else {
return EOF;
}
}
int putc(int c) {
return fputc(c,stdout);
}
int fputs(const char* s,FILE* stream) {
if (!stream->wr) {
errno=EBADF;
stream->error=1;
return EOF;
}
size_t len=strlen(s);
for (size_t i=0;i<len;i++) {
int c=fputc(s[i],stream);
if (c==EOF) {
return EOF;
}
}
return 1;
}
int puts(const char* s) {
return fputs(s,stdout);
}
size_t fwrite(void* buffer_ptr,size_t size,size_t count,FILE* stream) {
if (!stream->wr) {
errno=EBADF;
stream->error=1;
return 0;
}
char* buffer=(char*)buffer_ptr;
size_t bytes=size*count;
for (size_t i=0;i<bytes;i++) {
int c=fputc((uint8_t)buffer[i],stream);
if (c==EOF) {
return (size_t)(i/size);
}
}
return count;
}
int vfprintf(FILE* stream,const char* format,va_list arg) {
int c;
for(;*format!='\0';format++) {
if(*format!='%') {
c=fputc(*format,stream);
if (c==EOF) {
return EOF;
}
continue;
}
format++;
switch(*format) {
case 'c': {
int i=va_arg(arg,int);
c=fputc(i,stream);
if (c==EOF) {
return EOF;
}
break;
}
case 'd': {
int i=va_arg(arg,int); //Fetch Decimal/Integer argument
if(i<0) {
i=-i;
fputc('-',stream);
}
char str[11];
int_to_ascii(i,str);
c=fputs(str,stream);
if (c==EOF) {
return EOF;
}
break;
}
// case 'o': {
// int i=va_arg(arg,unsigned int); //Fetch Octal representation
// puts(convert(i,8));
// break;
// }
case 's': {
char* s=va_arg(arg,char*);
c=fputs(s,stream);
if (c==EOF) {
return EOF;
}
break;
}
case 'x': {
uint32_t i=va_arg(arg,uint32_t);
char str[11];
str[0]='\0';
hex_to_ascii(i,str);
c=fputs(str,stream);
if (c==EOF) {
return EOF;
}
break;
}
}
}
return 1;
}
int fprintf(FILE* stream,const char* format,...) {
va_list arg;
int code;
va_start(arg,format);
code=vfprintf(stream,format,arg);
va_end(arg);
if (code) {
return strlen(format);
} else {
return EOF;
}
}
int printf(const char* format,...) {
va_list arg;
int code;
va_start(arg,format);
code=vfprintf(stdout,format,arg);
va_end(arg);
if (code) {
return strlen(format);
} else {
return EOF;
}
}
int fseek(FILE* stream,long offset,int origin) {
if (origin==SEEK_SET) {
stream->pos=offset;
}
if (origin==SEEK_CUR) {
stream->pos+=offset;
}
return 0;
}
long ftell(FILE* stream) {
return stream->pos;
}
int fclose(FILE* stream) {
drvs[stream->type](FSOP_CLOSE,stream,NULL,NULL);
free(stream);
return 0;
}
int feof(FILE *stream) {
return stream->eof;
}
int ferror(FILE *stream) {
return stream->error;
}

21
stuff/vfs.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef VFS_H
#define VFS_H
#include <stdint.h>
#include <stdio.h>
typedef enum {
FSOP_MOUNT,
FSOP_OPEN,
FSOP_GETC,
FSOP_PUTC,
FSOP_CLOSE,
FSOP_UMOUNT
} fs_op;
typedef char (*fs_drv)(fs_op op,FILE* stream,void* data1,void* data2);
void init_vfs();
uint32_t register_fs(fs_drv drv,const char* type);
char mount(char* mntpnt,char* dev,char* type);
#endif