Add IDE driver and r/o ext2 fs driver

This commit is contained in:
pjht 2019-04-06 09:07:06 -05:00
parent d5c21bd0ae
commit 20ae5d1a31
15 changed files with 643 additions and 8 deletions

View File

@ -7,7 +7,7 @@ LIBC_OBJ = $(LIBC_SOURCES:.c=.o)
CC = $(shell cat psinfo/$(PLAT)/cc.txt)
GDB = $(shell cat psinfo/$(PLAT)/gdb.txt)
CFLAGS = -Isysroot/usr/include -Wextra -Wall -Wno-unused-parameter -g -ffreestanding
QFLAGS = -m 2G -boot d -cdrom os.iso -serial vc #-chardev socket,id=s1,port=3000,host=localhost -serial chardev:s1
QFLAGS = -hda ext2.img -m 2G -boot d -cdrom os.iso -serial vc #-chardev socket,id=s1,port=3000,host=localhost -serial chardev:s1
.PHONY: sysroot

View File

@ -10,8 +10,8 @@ floppy_bootsig_check: disabled=0
# no floppya
# no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=cdrom, path="os.iso", status=inserted, model="Generic 1234", biosdetect=auto
ata0-slave: type=none
ata0-master: type=disk, path=ext2.img, mode=flat, cylinders=65, heads=16, spt=63, model="Generic 1234", biosdetect=auto, translation=auto
ata0-slave: type=cdrom, path=os.iso, status=inserted, model="Generic 1234", biosdetect=auto
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata1-master: type=none
ata1-slave: type=none

210
drivers/i386/ide.c Normal file
View File

@ -0,0 +1,210 @@
#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 uint8_t* read_sect(int base,int slave,int lba) {
if (last_read_sector==lba && 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(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;
if (sect_data) {
free(sect_data);
}
sect_data=sect;
return sect;
}
static void write_sect(int base,int slave,int lba,uint8_t* sect) {
if (last_read_sector==lba) {
sect_data=sect;
}
if (!sect_data) {
last_read_sector=lba;
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));
}
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) {
int 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 0;
} else {
int 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(0x3f6,port_byte_in(0x3f6)|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(0x3f6,port_byte_in(0x3f6)|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(0x3f6,port_byte_in(0x3f6)|0x2);
// devfs_add(drv,"hdd");
// }
// }
}

View File

@ -74,8 +74,8 @@ static void checkFunction(pci_dev_common_info* info) {
max_devs+=32;
pci_devs=malloc(sizeof(pci_dev_common_info)*max_devs);
}
// pci_devs[pci_num_devs]=info;
// pci_num_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) {

6
drivers/ide.h Normal file
View File

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

3
ext2.img Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e7b85e285e01298d68e35b7510c428f88ad2ae9e4c633d533606c05e8f0f8e70
size 33554432

230
fs/ext2.c Normal file
View File

@ -0,0 +1,230 @@
#include "../kernel/vfs.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "ext2_structs.h"
ext2_superblock* supblks;
uint32_t* blk_size;
blk_grp** blk_grps;
char** mnts;
char** devs;
int num_mnts;
int max_mnts;
typedef struct {
int num;
inode inode;
char is_cont_valid;
char* contents;
} file_info;
void* read_blk(int blknum,FILE* f) {
void* block=malloc(sizeof(uint8_t)*1024);
fseek(f,blknum*1024,SEEK_SET);
fread(block,1,sizeof(uint8_t)*1024,f);
return block;
}
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=1024/sizeof(inode);
uint32_t blk=starting_blk+(index/inodes_per_blk);
uint32_t offset=index%inodes_per_blk;
inode* inodes=read_blk(blk,f);
return inodes[offset];
}
char** get_dir_listing(uint32_t inode_num,FILE* f,int num) {
char** names=malloc(sizeof(char*)*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;
dir_entry* dir=read_blk(dir_inode.i_block[0],f);
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;
names=realloc(names,sizeof(char*)*max_len);
}
names[num_entries_used]=malloc(current_entry->name_len+1);
strcpy(names[num_entries_used],current_entry->file_name);
names[num_entries_used][(int)current_entry->name_len]='\0';
num_entries_used++;
tot_size+=current_entry->rec_len;
current_entry=(dir_entry*)(((uint32_t)current_entry)+current_entry->rec_len);
}
if(num_entries_used==max_len) {
max_len+=1;
names=realloc(names,sizeof(char*)*max_len);
}
names[num_entries_used]=NULL;
return names;
}
void free_dir_listing(char** names) {
for(int i=0;names[i]!=NULL;i++) {
free(names[i]);
}
free(names);
}
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;
dir_entry* dir=read_blk(dir_inode.i_block[0],f);
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=(dir_entry*)(((uint32_t)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) {
uint32_t inode=0;
*got_inode=0;
char** names=get_dir_listing(dir_inode_num,f,num);
for(int i=0;names[i]!=NULL;i++) {
if (strcmp(names[i],name)==0) {
dir_entry* entry=read_dir_entry(dir_inode_num,i,f,num);
inode=entry->inode;
*got_inode=1;
break;
}
}
free_dir_listing(names);
return inode;
}
char* fname_for_inode(uint32_t dir_inode_num, uint32_t inode_num,FILE* f,int num) {
for(int i=0;;i++) {
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));
mnts=realloc(mnts,sizeof(char*)*(max_mnts+32));
devs=realloc(devs,sizeof(char*)*(max_mnts+32));
max_mnts+=32;
}
FILE* f=fopen(dev,"r");
ext2_superblock* supblk=read_blk(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);
blk_grps=malloc(sizeof(blk_grp*)*num_blk_grps);
blk_grp* blk_group=read_blk(2,f);
blk_grps[num_mnts]=malloc(sizeof(blk_grp)*num_blk_grps);
for (uint32_t i=0;i<num_blk_grps;i++) {
blk_grps[num_mnts][i]=*blk_group;
blk_group++;
};
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");
char got_inode;
uint32_t inode_num=inode_for_fname(2,stream->path,&got_inode,f,data->num);
if (got_inode) {
data->inode=read_inode(inode_num,f,data->num);
fclose(f);
return 1;
} else {
fclose(f);
return 0;
}
} 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_blk((data->inode).i_block[0],f);
fclose(f);
data->is_cont_valid=1;
data->contents=contents;
}
if (stream->pos>strlen(contents)) {
*((int*)data1)=EOF;
stream->eof=1;
return 1;
}
*((int*)data1)=contents[stream->pos];
stream->pos++;
return 1;
}
if (op==FSOP_PUTC) {
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);
mnts=malloc(sizeof(char*)*32);
devs=malloc(sizeof(char*)*32);
num_mnts=0;
max_mnts=32;
register_fs(drv,"ext2");
}

6
fs/ext2.h Normal file
View File

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

138
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_ro_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_RO_COMPAT_SPARSE_SUPER=1,
EXT2_FEATURE_RO_COMPAT_LARGE_FILE=2,
EXT2_FEATURE_RO_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_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)) dir_entry;
#endif

View File

@ -14,6 +14,8 @@
#include <grub/multiboot.h>
#include "klog.h"
#include "elf.h"
#include "../drivers/ide.h"
#include "../fs/ext2.h"
static long initrd_sz;
static char* initrd;
@ -111,6 +113,36 @@ static void init() {
int val=prog();
klog("INFO","RAN PROG:%d",val);
}
ide_init();
init_ext2();
mount("/","/dev/hda","ext2");
FILE* f=fopen("/file","r");
char str[256];
fgets(str,256,f);
str[strlen(str)-1]='\0';
klog("INFO","Got string %s",str);
fgets(str,256,f);
str[strlen(str)-1]='\0';
klog("INFO","Got string %s",str);
fclose(f);
// ext2_parse();
// char** names=get_dir_listing(2);
// for(int i=0;names[i]!=NULL;i++) {
// printf("%s ",names[i]);
// }
// printf("\n");
// free_dir_listing(names);
// char* name="file";
// char got_inode;
// uint32_t inode_num=inode_for_fname(2,name,&got_inode);
// klog("INFO","Contents of file \"file\":");
// if (got_inode) {
// inode file_inode=read_inode(inode_num);
// char* contents=read_blk(file_inode.i_block[0]);
// printf("%s",contents);
// } else {
// printf("%s: No such file or directory\n",name);
// }
for(;;) {
yield();
}

View File

@ -5,3 +5,11 @@ float ceilf(float num) {
}
return (float)(inum+1);
}
double ceil(double num) {
int inum=(int)num;
if (num==(double)inum) {
return (double)inum;
}
return (double)(inum+1);
}

View File

@ -2,5 +2,6 @@
#define MATH_H
float ceilf(float num);
double ceil(double num);
#endif

View File

@ -7,7 +7,7 @@ typedef struct {
char* mntpnt;
const char* path;
uint32_t type;
long pos;
unsigned long pos;
int eof;
void* data;
} FILE;

View File

@ -2,5 +2,6 @@
#define MATH_H
float ceilf(float num);
double ceil(double num);
#endif

View File

@ -7,7 +7,7 @@ typedef struct {
char* mntpnt;
const char* path;
uint32_t type;
long pos;
unsigned long pos;
int eof;
void* data;
} FILE;