Remove all drivers and fs code from kernel
This commit is contained in:
parent
9f79bf1aae
commit
204fec4407
34
Makefile
34
Makefile
@ -22,41 +22,41 @@ QFLAGS = -hda ext2.img -m 2G -boot d -cdrom os.iso -serial vc #-chardev socket,
|
||||
all: os.iso
|
||||
|
||||
run: os.iso
|
||||
$(EMU) $(QFLAGS) -monitor stdio
|
||||
@$(EMU) $(QFLAGS) -monitor stdio
|
||||
|
||||
debug: os.iso kernel/kernel.elf
|
||||
$(EMU) -s $(QFLAGS) &
|
||||
$(GDB) -ex "target remote localhost:1234" -ex "symbol-file kernel/kernel.elf"
|
||||
@$(EMU) -s $(QFLAGS) &
|
||||
@$(GDB) -ex "target remote localhost:1234" -ex "symbol-file kernel/kernel.elf"
|
||||
|
||||
os.iso: kernel/kernel.elf initrd/* initrd/prog.elf
|
||||
cp kernel/kernel.elf iso/boot
|
||||
ruby makeinitrd.rb initrd iso/boot/initrd
|
||||
grub-mkrescue -o $@ iso
|
||||
@cp kernel/kernel.elf iso/boot
|
||||
@ruby makeinitrd.rb initrd iso/boot/initrd
|
||||
@grub-mkrescue -o $@ iso
|
||||
|
||||
initrd/prog.elf: prog/* kernel/start.o
|
||||
cd prog && make
|
||||
cp prog/prog.elf initrd/init
|
||||
@cd prog && make
|
||||
@cp prog/prog.elf initrd/init
|
||||
|
||||
kernel/kernel.elf: $(OBJ) $(ASM_OBJ) $(S_ASM_OBJ) libc/libc.a
|
||||
$(CC) -z max-page-size=4096 -Xlinker -n -T cpu/$(PLAT)/linker.ld -o $@ $(CFLAGS) -nostdlib $^ -lgcc
|
||||
@$(CC) -z max-page-size=4096 -Xlinker -n -T cpu/$(PLAT)/linker.ld -o $@ $(CFLAGS) -nostdlib $^ -lgcc
|
||||
|
||||
sysroot: $(LIBC_HEADERS)
|
||||
mkdir -p sysroot/usr/include
|
||||
cp -r libc/* sysroot/usr/include
|
||||
rm -f sysroot/usr/include/libc.a sysroot/usr/include/*.o sysroot/usr/include/*/*.o sysroot/usr/include/*.c sysroot/usr/include/*/*.c
|
||||
@mkdir -p sysroot/usr/include
|
||||
@cp -r libc/* sysroot/usr/include
|
||||
@rm -f sysroot/usr/include/libc.a sysroot/usr/include/*.o sysroot/usr/include/*/*.o sysroot/usr/include/*.c sysroot/usr/include/*/*.c
|
||||
|
||||
|
||||
libc/libc.a: $(LIBC_OBJ)
|
||||
$(AR) rcs $@ $^
|
||||
@$(AR) rcs $@ $^
|
||||
|
||||
%.o: %.c sysroot
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.asm
|
||||
$(NASM) $< -o $@
|
||||
@$(NASM) $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
$(AS) $< -o $@
|
||||
@$(AS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ) $(OBJ) $(ASM_OBJ) $(S_ASM_OBJ) libc/libc.a kernel/cstart.o cpu/memory.h os.iso */*.elf iso/boot/initrd.tar
|
||||
@rm -rf $(OBJ) $(OBJ) $(ASM_OBJ) $(S_ASM_OBJ) libc/libc.a kernel/cstart.o cpu/memory.h os.iso */*.elf iso/boot/initrd.tar
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "ports.h"
|
||||
#include "paging.h"
|
||||
#include "../halt.h"
|
||||
#include "../../drivers/vga.h"
|
||||
#include "../../kernel/vga_err.h"
|
||||
#include "../tasking.h"
|
||||
#include "interrupt.h"
|
||||
#include "address_spaces.h"
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "paging_helpers.h"
|
||||
#include "paging.h"
|
||||
#include "pmem.h"
|
||||
#include "../../kernel/vga_err.h"
|
||||
#include <klog.h>
|
||||
|
||||
static uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||
@ -82,7 +83,7 @@ uint32_t find_free_pages(int num_pages) {
|
||||
}
|
||||
}
|
||||
if (remaining_blks!=0) {
|
||||
klog("PANIC","Out of memory");
|
||||
vga_write_string("[PANIC] Out of memory");
|
||||
}
|
||||
return bmap_index;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
#include "paging_helpers.h"
|
||||
|
||||
#define NUM_KERN_DIRS 2
|
||||
#define NUM_KERN_DIRS 1
|
||||
|
||||
void map_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr);
|
||||
void* alloc_pages(int num_pages);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <grub/multiboot2.h>
|
||||
#include "../halt.h"
|
||||
#include "../../drivers/vga.h"
|
||||
#include "../../kernel/vga_err.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <klog.h>
|
||||
|
@ -1,217 +0,0 @@
|
||||
#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");
|
||||
// }
|
||||
// }
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#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
|
@ -1,159 +0,0 @@
|
||||
#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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef IDE_H
|
||||
#define IDE_H
|
||||
|
||||
void ide_init();
|
||||
|
||||
#endif
|
@ -1,6 +0,0 @@
|
||||
#ifndef PARALLEL_H
|
||||
#define PARALLEL_H
|
||||
|
||||
void parallel_init();
|
||||
|
||||
#endif
|
@ -1,49 +0,0 @@
|
||||
#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
|
@ -1,6 +0,0 @@
|
||||
#ifndef PS2_EXT_H
|
||||
#define PS2_EXT_H
|
||||
|
||||
void ps2_init();
|
||||
|
||||
#endif
|
@ -1,7 +0,0 @@
|
||||
#ifndef SERIAL_H
|
||||
#define SERIAL_H
|
||||
#include <stdint.h>
|
||||
|
||||
void serial_init();
|
||||
|
||||
#endif
|
@ -1,7 +0,0 @@
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
void wait(int milli);
|
||||
void timer_init();
|
||||
|
||||
#endif
|
@ -1,29 +0,0 @@
|
||||
#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
|
@ -1,84 +0,0 @@
|
||||
#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
fs/devfs.c
71
fs/devfs.c
@ -1,71 +0,0 @@
|
||||
#include "../kernel/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++;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#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
fs/ext2.c
479
fs/ext2.c
@ -1,479 +0,0 @@
|
||||
#include "../kernel/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");
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
#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
fs/initrd.c
85
fs/initrd.c
@ -1,85 +0,0 @@
|
||||
#include "../kernel/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");
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef INITRD_H
|
||||
#define INITRD_H
|
||||
|
||||
uint32_t initrd_init();
|
||||
|
||||
#endif
|
@ -6,7 +6,7 @@
|
||||
#include <grub/multiboot2.h>
|
||||
#include <stdint.h>
|
||||
#include "../cpu/cpu_init.h"
|
||||
#include "../drivers/vga.h"
|
||||
#include "vga_err.h"
|
||||
#include "elf.h"
|
||||
|
||||
static long initrd_sz;
|
||||
@ -33,11 +33,7 @@ static void read_initrd(struct multiboot_boot_header_tag* tags) {
|
||||
void kmain(struct multiboot_boot_header_tag* hdr) {
|
||||
tags=hdr;
|
||||
cpu_init(tags);
|
||||
text_fb_info info;
|
||||
info.address=(char*)0xC00B8000;
|
||||
info.width=80;
|
||||
info.height=25;
|
||||
vga_init(info);
|
||||
vga_init((char*)0xC00B8000);
|
||||
read_initrd(tags);
|
||||
int pos=0;
|
||||
uint32_t datapos;
|
||||
|
101
kernel/parts.c
101
kernel/parts.c
@ -1,101 +0,0 @@
|
||||
#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++;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef PARTS_H
|
||||
#define PARTS_H
|
||||
|
||||
void load_parts(const char* path);
|
||||
|
||||
#endif
|
357
kernel/vfs.c
357
kernel/vfs.c
@ -1,357 +0,0 @@
|
||||
#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
kernel/vfs.h
21
kernel/vfs.h
@ -1,21 +0,0 @@
|
||||
#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
|
20
kernel/vga_err.c
Normal file
20
kernel/vga_err.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "../cpu/i386/ports.h"
|
||||
#include <string.h>
|
||||
#define VGA_BLACK 0
|
||||
#define VGA_WHITE 15
|
||||
static char* screen;
|
||||
|
||||
static void set_char(int x,char c) {
|
||||
screen[x*2]=c;
|
||||
screen[x*2+1]=(VGA_BLACK<<4)|VGA_WHITE;
|
||||
}
|
||||
|
||||
void vga_init(char* addr) {
|
||||
screen=addr;
|
||||
}
|
||||
|
||||
void vga_write_string(const char* string) {
|
||||
for (size_t i=0;i<strlen(string);i++) {
|
||||
set_char(i,string[i]);
|
||||
}
|
||||
}
|
7
kernel/vga_err.h
Normal file
7
kernel/vga_err.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef VGA_ERR_H
|
||||
#define VGA_ERR_H
|
||||
|
||||
void vga_init(char* screen);
|
||||
void vga_write_string(const char *string);
|
||||
|
||||
#endif
|
30
libc/klog.c
30
libc/klog.c
@ -1,15 +1,15 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int vfprintf(FILE* stream,const char* format,va_list arg);
|
||||
|
||||
void klog(char* level,char* s,...) {
|
||||
if (stdout!=NULL) {
|
||||
va_list arg;
|
||||
va_start(arg,s);
|
||||
printf("[%s] ",level);
|
||||
vfprintf(stdout,s,arg);
|
||||
printf("\n");
|
||||
va_end(arg);
|
||||
}
|
||||
}
|
||||
// #include <stdarg.h>
|
||||
// #include <stdio.h>
|
||||
//
|
||||
// int vfprintf(FILE* stream,const char* format,va_list arg);
|
||||
//
|
||||
// void klog(char* level,char* s,...) {
|
||||
// if (stdout!=NULL) {
|
||||
// va_list arg;
|
||||
// va_start(arg,s);
|
||||
// printf("[%s] ",level);
|
||||
// vfprintf(stdout,s,arg);
|
||||
// printf("\n");
|
||||
// va_end(arg);
|
||||
// }
|
||||
// }
|
||||
|
Loading…
Reference in New Issue
Block a user