# HG changeset patch # User John Tsiombikas # Date 1323431055 -7200 # Node ID 7ff2b4971216ece060307be9fda6ca28cc728c02 # Parent 2f555c81ae6748f0d50bfebe8fc7a1b8fd05d47b started work on the filesystem diff -r 2f555c81ae67 -r 7ff2b4971216 fstools/mkfs/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fstools/mkfs/Makefile Fri Dec 09 13:44:15 2011 +0200 @@ -0,0 +1,23 @@ +ksrc = ../../src + +obj = mkfs.o fs.o +dep = $(obj:.o=.d) +bin = mkfs + +CC = gcc +CFLAGS = -pedantic -Wall -g -I$(ksrc) + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +-include $(dep) + +fs.o: $(ksrc)/fs.c + $(CC) $(CFLAGS) -c $< -o $@ + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) $(dep) diff -r 2f555c81ae67 -r 7ff2b4971216 fstools/mkfs/mkfs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fstools/mkfs/mkfs.c Fri Dec 09 13:44:15 2011 +0200 @@ -0,0 +1,147 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#endif +#ifdef __darwin__ +#include +#endif +#include "fs.h" + +int mkfs(int fd, int blksize, uint32_t nblocks); +uint32_t get_block_count(int fd, int blksize); +int user_readblock(int dev, uint32_t blk, void *buf); +int user_writeblock(int dev, uint32_t blk, void *buf); +int parse_args(int argc, char **argv); + +int fd; +uint32_t num_blocks; + +int main(int argc, char **argv) +{ + if(parse_args(argc, argv) == -1) { + return 1; + } + + if((num_blocks = get_block_count(fd, BLKSZ)) == 0) { + fprintf(stderr, "could not determine the number of blocks\n"); + return 1; + } + printf("total blocks: %u\n", (unsigned int)num_blocks); + + if(mkfs(fd, num_blocks) == -1) { + return 1; + } + + return 0; +} + +int mkfs(int fd, int blksize, uint32_t nblocks) +{ + struct superblock *sb; + + if(!(sb = malloc(BLKSZ))) { + perror("failed to allocate memory"); + return -1; + } +} + +uint32_t get_block_count(int fd, int blksize) +{ + unsigned long sz = 0; + uint64_t sz64 = 0; + struct stat st; + +#ifdef BLKGETSIZE64 + if(ioctl(fd, BLKGETSIZE64, &sz64) != -1) { + return sz64 / blksize; + } +#endif + +#ifdef BLKGETSIZE + if(ioctl(fd, BLKGETSIZE, &sz) != -1) { + return sz / (blksize / 512); + } +#endif + +#ifdef DKIOCGETBLOCKCOUNT + if(ioctl(fd, DKIOCGETBLOCKCOUNT, &sz64) != -1) { + return sz64 / (blksize / 512); + } +#endif + + if(fstat(fd, &st) != -1 && S_ISREG(st.st_mode)) { + return st.st_size / blksize; + } + + return 0; +} + +int user_readblock(int dev, uint32_t blk, void *buf) +{ + if(lseek(fd, blk * BLKSZ, SEEK_SET) == -1) { + return -1; + } + if(read(fd, buf, BLKSZ) < BLKSZ) { + return -1; + } + return 0; +} + +int user_writeblock(int dev, uint32_t blk, void *buf) +{ + if(lseek(fd, blk * BLKSZ, SEEK_SET) == -1) { + return -1; + } + if(write(fd, buf, BLKSZ) < BLKSZ) { + return -1; + } + return 0; +} + +int parse_args(int argc, char **argv) +{ + int i; + + fd = -1; + + for(i=1; i\n", argv[0]); + exit(0); + + default: + goto invalid; + } + } else { + if(fd != -1) { + goto invalid; + } + + if((fd = open(argv[i], O_RDWR)) == -1) { + fprintf(stderr, "failed to open %s: %s\n", argv[i], strerror(errno)); + return -1; + } + } + } + + if(fd == -1) { + fprintf(stderr, "you must specify a device or image file\n"); + return -1; + } + + return 0; + +invalid: + fprintf(stderr, "invalid argument: %s\n", argv[i]); + return -1; +} diff -r 2f555c81ae67 -r 7ff2b4971216 include/kdef.h --- a/include/kdef.h Thu Dec 08 18:19:35 2011 +0200 +++ b/include/kdef.h Fri Dec 09 13:44:15 2011 +0200 @@ -32,6 +32,8 @@ #define EAGAIN 1 #define EINVAL 2 #define ECHILD 3 + +#define EBUG 255 /* not implemented yet */ #endif /* errno.h */ @@ -47,8 +49,16 @@ #define SYS_WAITPID 4 #define SYS_GETPID 5 #define SYS_GETPPID 6 +#define SYS_MOUNT 7 +#define SYS_UMOUNT 8 +#define SYS_OPEN 9 +#define SYS_CLOSE 10 +#define SYS_READ 11 +#define SYS_WRITE 12 +#define SYS_LSEEK 13 -#define NUM_SYSCALLS 7 +/* keep this one more than the last syscall */ +#define NUM_SYSCALLS 14 #endif /* syscall.h */ diff -r 2f555c81ae67 -r 7ff2b4971216 src/ata.c --- a/src/ata.c Thu Dec 08 18:19:35 2011 +0200 +++ b/src/ata.c Fri Dec 09 13:44:15 2011 +0200 @@ -110,6 +110,16 @@ return ndev; } +uint64_t ata_num_sectors(int devno) +{ + struct device *dev = devices + devno; + + if(dev->nsect_lba48) { + return dev->nsect_lba48; + } + return dev->nsect_lba; +} + int ata_read_pio(int devno, uint64_t sect, void *buf) { return readwrite_pio(devno, sect, buf, read_data); diff -r 2f555c81ae67 -r 7ff2b4971216 src/ata.h --- a/src/ata.h Thu Dec 08 18:19:35 2011 +0200 +++ b/src/ata.h Fri Dec 09 13:44:15 2011 +0200 @@ -4,6 +4,7 @@ void init_ata(void); int ata_num_devices(void); +uint64_t ata_num_sectors(int devno); int ata_read_pio(int devno, uint64_t sect, void *buf); int ata_write_pio(int devno, uint64_t sect, void *buf); diff -r 2f555c81ae67 -r 7ff2b4971216 src/bdev.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/bdev.c Fri Dec 09 13:44:15 2011 +0200 @@ -0,0 +1,86 @@ +#include +#include +#include "bdev.h" +#include "ata.h" +#include "part.h" + +#define MINOR_DISK(x) (((x) >> 4) & 0xf) +#define MINOR_PART(x) ((x) & 0xf) + +struct block_device *blk_open(dev_t dev) +{ + struct block_device *bdev; + int i, minor, devno, part; + + /* XXX for now ignore the major number as we only have ata devices */ + minor = DEV_MINOR(dev); + devno = MINOR_DISK(minor); + part = MINOR_PART(minor); + + bdev = malloc(sizeof *bdev); + assert(bdev); + + bdev->ata_dev = devno; + + if(part) { + struct partition *plist = get_part_list(devno); + assert(plist); + + for(i=1; inext; + } + if(!plist) { + free(bdev); + free_part_list(plist); + return 0; + } + + bdev->offset = SECT_TO_BLK(plist->start_sect); + bdev->size = SECT_TO_BLK(plist->size_sect); + + free_part_list(plist); + } else { + bdev->offset = 0; + bdev->size = SECT_TO_BLK(ata_num_sectors(devno)); + } + + return bdev; +} + +void blk_close(struct block_device *bdev) +{ + free(bdev); +} + +#define NSECT (BLKSZ / 512) + +int blk_read(struct block_device *bdev, uint32_t blk, void *buf) +{ + int i; + char *ptr = buf; + uint32_t sect = blk * NSECT; + + for(i=0; iata_dev, sect++, ptr) == -1) { + return -1; + } + ptr += 512; + } + return 0; +} + +int blk_write(struct block_device *bdev, uint32_t blk, void *buf) +{ + int i; + char *ptr = buf; + uint32_t sect = blk * NSECT; + + for(i=0; iata_dev, sect++, ptr) == -1) { + return -1; + } + ptr += 512; + } + return 0; +} diff -r 2f555c81ae67 -r 7ff2b4971216 src/bdev.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/bdev.h Fri Dec 09 13:44:15 2011 +0200 @@ -0,0 +1,19 @@ +#ifndef BDEV_H_ +#define BDEV_H_ + +#include "fs.h" /* for dev_t */ + +/* TODO buffer cache */ + +struct block_device { + int ata_dev; + uint32_t offset, size; +}; + +struct block_device *blk_open(dev_t dev); +void blk_close(struct block_device *bdev); + +int blk_read(struct block_device *bdev, uint32_t blk, void *buf); +int blk_write(struct block_device *bdev, uint32_t blk, void *buf); + +#endif /* BDEV_H_ */ diff -r 2f555c81ae67 -r 7ff2b4971216 src/file.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/file.h Fri Dec 09 13:44:15 2011 +0200 @@ -0,0 +1,11 @@ +#ifndef FILE_H_ +#define FILE_H_ + +#include "fs.h" + +struct file { + struct inode *inode; + long ptr; +}; + +#endif /* FILE_H_ */ diff -r 2f555c81ae67 -r 7ff2b4971216 src/fs.c --- a/src/fs.c Thu Dec 08 18:19:35 2011 +0200 +++ b/src/fs.c Fri Dec 09 13:44:15 2011 +0200 @@ -1,48 +1,61 @@ +/* This code is used by the kernel AND by userspace filesystem-related tools. + * The kernel-specific parts are conditionally compiled in #ifdef KERNEL blocks + * the rest of the code should be independent. + */ #include #include #include +#include #include "fs.h" +#include "part.h" + +#ifdef KERNEL #include "ata.h" -#include "part.h" #include "panic.h" - -#define MAGIC 0xccf5ccf5 -#define BLKSZ 1024 - -typedef uint32_t blkid; - -struct superblock { - uint32_t magic; - - blkid istart; - unsigned int icount; - - blkid dstart; - unsigned int dcount; -}; +#endif struct filesys { int dev; struct partition part; struct superblock *sb; + + struct filesys *next; }; static int find_rootfs(struct filesys *fs); +static int readblock(int dev, uint32_t blk, void *buf); +static int writeblock(int dev, uint32_t blk, void *buf); /* root device & partition */ -static struct filesys root; +static struct filesys *fslist; + +int sys_mount(char *mtpt, char *devname, unsigned int flags) +{ + if(strcmp(mtpt, "/") != 0) { + printf("mount: only root can be mounted at the moment\n"); + return -EBUG; + } + + /* mounting root filesystem */ + if(fslist) { + +} void init_fs(void) { root.sb = malloc(512); assert(root.sb); +#ifdef KERNEL if(find_rootfs(&root) == -1) { panic("can't find root filesystem\n"); } +#endif } + +#ifdef KERNEL #define PART_TYPE 0xcc static int find_rootfs(struct filesys *fs) { @@ -59,7 +72,7 @@ /* found the correct partition, now read the superblock * and make sure it's got the correct magic id */ - ata_read_pio(i, p->start_sect + 2, fs->sb); + readblock(i, p->start_sect / 2 + 1, fs->sb); if(fs->sb->magic == MAGIC) { printf("found root ata%dp%d\n", i, partid); @@ -75,3 +88,33 @@ } return -1; } + +#define NSECT (BLKSZ / 512) + +static int readblock(struct block_device *bdev, uint32_t blk, void *buf) +{ + return blk_read(bdev, blk, buf); +} + +static int writeblock(struct block_device *bdev, uint32_t blk, void *buf) +{ + return blk_write(bdev, blk, buf); +} +#else + +/* if this is compiled as part of the user-space tools instead of the kernel + * forward the call to a user read/write block function supplied by the app. + */ +int user_readblock(uint32_t, void*); +int user_writeblock(uint32_t, void*); + +static int readblock(struct block_device *bdev, uint32_t blk, void *buf) +{ + return user_readblock(blk, buf); +} + +static int writeblock(struct block_device *bdev, uint32_t blk, void *buf) +{ + return user_writeblock(blk, buf); +} +#endif /* KERNEL */ diff -r 2f555c81ae67 -r 7ff2b4971216 src/fs.h --- a/src/fs.h Thu Dec 08 18:19:35 2011 +0200 +++ b/src/fs.h Fri Dec 09 13:44:15 2011 +0200 @@ -1,7 +1,75 @@ #ifndef FS_H_ #define FS_H_ -void init_fs(void); +#include + +#define MAGIC 0xccf5ccf5 +#define BLKSZ 1024 + +#define SECT_TO_BLK(x) ((x) / (BLKSZ / 512)) + +#define DEV_MAJOR(dev) (((dev) >> 8) & 0xff) +#define DEV_MINOR(dev) ((dev) & 0xff) + + +typedef uint32_t dev_t; +typedef uint32_t blkid; + +struct superblock { + uint32_t magic; /* magic number */ + int ver; /* filesystem version */ + int blksize; /* only BLKSZ supported at the moment */ + + /* total number of blocks */ + unsigned int num_blocks; + /* inode allocation bitmap start and count */ + blkid ibm_start; + unsigned int ibm_count; + /* inode table start and count */ + blkid itbl_start; + unsigned int itbl_count; + /* data block allocation bitmap start and count */ + blkid dbm_start; + unsigned int dbm_count; + /* data blocks start and count */ + blkid data_start; + unsigned int data_count; + + int root_ino; /* root direcotry inode */ + + /* the following are valid only at runtime, ignored on disk */ + uint32_t *ibm; /* memory inode bitmap */ + uint32_t *dbm; /* memory datablock bitmap */ + +} __attribute__((packed)); + + +/* 20 direct blocks + 10 attributes + 2 indirect = 128 bytes per inode */ +#define NDIRBLK 20 +struct inode { + int ino; + int uid, gid, mode; + int nlink; + dev_t dev; + uint32_t atime, ctime, mtime; + uint32_t size; + blkid blk[NDIRBLK]; /* direct blocks */ + blkid ind; /* indirect */ + blkid dind; /* double-indirect */ +} __attribute__((packed)); + + +int sys_mount(char *mntpt, char *devname, unsigned int flags); +int sys_umount(char *devname); + +int sys_open(char *pathname, int flags, unsigned int mode); +int sys_close(int fd); + +int sys_read(int fd, void *buf, int sz); +int sys_write(int fd, void *buf, int sz); +long sys_lseek(int fd, long offs, int from); + +int lookup_path(const char *path); #endif /* FS_H_ */ diff -r 2f555c81ae67 -r 7ff2b4971216 src/proc.c --- a/src/proc.c Thu Dec 08 18:19:35 2011 +0200 +++ b/src/proc.c Fri Dec 09 13:44:15 2011 +0200 @@ -165,6 +165,9 @@ p = proc + pid; parent = get_current_proc(); + /* copy file table */ + memcpy(p->files, parent->files, sizeof p->files); + /* allocate a kernel stack for the new process */ if((p->kern_stack_pg = pgalloc(KERN_STACK_SIZE / PGSIZE, MEM_KERNEL)) == -1) { return -EAGAIN; diff -r 2f555c81ae67 -r 7ff2b4971216 src/proc.h --- a/src/proc.h Thu Dec 08 18:19:35 2011 +0200 +++ b/src/proc.h Fri Dec 09 13:44:15 2011 +0200 @@ -4,8 +4,10 @@ #include #include "asmops.h" #include "rbtree.h" +#include "file.h" #define MAX_PROC 128 +#define MAX_FD 64 struct context { /*struct registers regs;*/ /* saved general purpose registers */ @@ -46,6 +48,9 @@ struct context ctx; + /* open files */ + struct file files[MAX_FD]; + struct process *child_list; struct process *next, *prev; /* for the scheduler queues */ diff -r 2f555c81ae67 -r 7ff2b4971216 src/syscall.c --- a/src/syscall.c Thu Dec 08 18:19:35 2011 +0200 +++ b/src/syscall.c Fri Dec 09 13:44:15 2011 +0200 @@ -4,6 +4,7 @@ #include "proc.h" #include "sched.h" #include "timer.h" +#include "fs.h" static int (*sys_func[NUM_SYSCALLS])(); @@ -21,6 +22,14 @@ sys_func[SYS_GETPID] = sys_getpid; /* proc.c */ sys_func[SYS_GETPPID] = sys_getppid; /* proc.c */ + sys_func[SYS_MOUNT] = sys_mount; /* fs.c */ + sys_func[SYS_UMOUNT] = sys_umount; /* fs.c */ + sys_func[SYS_OPEN] = sys_open; /* fs.c */ + sys_func[SYS_CLOSE] = sys_close; /* fs.c */ + sys_func[SYS_READ] = sys_read; /* fs.c */ + sys_func[SYS_WRITE] = sys_write; /* fs.c */ + sys_func[SYS_LSEEK] = sys_lseek; /* fs.c */ + interrupt(SYSCALL_INT, syscall); }