├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bochsrc ├── fs ├── Makefile ├── buffer.c ├── dcache.c ├── file.c ├── file_system.c ├── inode.c ├── libfs.c ├── lorem.sh ├── minix1fs │ ├── Makefile │ ├── minix_bitmap.c │ ├── minix_dcache.c │ ├── minix_fs.c │ ├── minix_inode.c │ └── minix_super.c ├── namei.c ├── pipefs │ ├── Makefile │ ├── pipe_fs.c │ ├── pipe_inode.c │ └── pipe_super.c ├── ramfs │ ├── Makefile │ ├── ram_fs.c │ ├── ramfs_inode.c │ └── ramfs_super.c ├── rootfs │ ├── Makefile │ ├── root_fs.c │ ├── root_inode.c │ └── root_super.c ├── script.sh ├── shell.sh ├── super.c ├── ttyfs │ ├── Makefile │ ├── tty_fs.c │ ├── tty_inode.c │ └── tty_super.c ├── txt2bin └── vfsmount.c ├── img ├── Screenshot from 2016-03-15 21-02-01.png └── Screenshot from 2016-03-15 21-07-35.png ├── include ├── args.h ├── asm │ ├── atomic.h │ ├── bitops.h │ ├── irqflag.h │ └── x86.h ├── drivers │ ├── hd.h │ ├── ide.h │ ├── pcireg.h │ └── sata.h ├── errno.h ├── fcntl.h ├── fuckOS │ ├── assert.h │ ├── cpu.h │ ├── dcache.h │ ├── device.h │ ├── fs.h │ ├── hd.h │ ├── kernel.h │ ├── keyboard.h │ ├── keymap.h │ ├── lapic.h │ ├── libfs.h │ ├── list.h │ ├── minixfs.h │ ├── namei.h │ ├── pci.h │ ├── pic_8259A.h │ ├── pidmap.h │ ├── pipe.h │ ├── ramfs.h │ ├── rbtree.h │ ├── rootfs.h │ ├── sched.h │ ├── task.h │ ├── time.h │ ├── trap.h │ ├── tty.h │ └── ttyfs.h ├── lib.h ├── mm │ ├── layout.h │ ├── mm.h │ ├── mmu.h │ ├── mmzone.h │ ├── pages.h │ ├── pgtable-2level.h │ ├── pgtable-3level.h │ └── slab.h ├── stdarg.h ├── stdio.h ├── string.h ├── sys │ ├── elf.h │ ├── multiboot2.h │ ├── stat.h │ └── system.h ├── syscall.h ├── time.h ├── types.h └── unistd.h ├── iso └── boot │ └── grub │ └── grub.cfg ├── kernel.ld ├── kernel ├── 123 │ ├── bitmap.c │ ├── buffer.c │ ├── file_dev.c │ ├── inode.c │ ├── namei.c │ └── super.c ├── .task.c.swp ├── Makefile ├── block │ ├── Makefile │ ├── ide.c │ ├── rw_block.c │ └── sata.c ├── char │ ├── Makefile │ ├── console.c │ ├── keyboard.c │ └── tty_io.c ├── cpu.c ├── init │ ├── Makefile │ ├── detect.c │ ├── entry.S │ ├── main.c │ ├── mpentry.S │ ├── real │ ├── realmode │ └── tmpset.c ├── mm │ ├── Makefile │ ├── bootmm.c │ ├── mm.c │ ├── page.c │ ├── slab.c │ └── zone.c ├── panic.c ├── pci.c ├── pidmap.c ├── printk.c ├── rbtree.c ├── sched.c ├── syscall │ ├── Makefile │ ├── brk.c │ ├── dev_close.c │ ├── dev_create.c │ ├── dev_mkdir.c │ ├── dev_open.c │ ├── dev_read.c │ ├── dev_write.c │ ├── dup.c │ ├── execve.c │ ├── exit.c │ ├── fdtype.c │ ├── fork.c │ ├── mount.c │ ├── pipe.c │ ├── printf.c │ └── wait.c ├── task.c ├── time.c └── trap │ ├── Makefile │ ├── breakpoint.c │ ├── divzero.c │ ├── geneprot.c │ ├── irq_kbd.c │ ├── irq_timer.c │ ├── lapic.c │ ├── page_fault.c │ ├── pic_8259A.c │ ├── syscall.c │ ├── trap.c │ └── trapentry.S ├── lib ├── Makefile ├── args.c ├── brk.c ├── close.c ├── create.c ├── dup.c ├── entry.S ├── execve.c ├── exit.c ├── fork.c ├── getpid.c ├── malloc.c ├── mkdir.c ├── open.c ├── pipe.c ├── printf.c ├── printfmt.c ├── read.c ├── readline.c ├── string.c ├── syscall.c ├── tdtype.c ├── wait.c └── write.c └── user ├── Makefile ├── badsegment.c ├── buggyhello.c ├── buggyhello2.c ├── cat.c ├── divzero.c ├── echo.c ├── evilhello.c ├── forktree.c ├── hello.c ├── idle.c ├── init.c ├── initsh.c ├── num.c ├── primespipe.c ├── sh.c ├── softint.c ├── testargv.c ├── testclose.c ├── testcreate.c ├── testdup.c ├── testexec.c ├── testexit.c ├── testfork.c ├── testmalloc.c ├── testmkdir.c ├── testopen.c ├── testpipe.c ├── testpipe0.c ├── testread.c ├── teststack.c ├── testtype.c ├── testwait.c ├── testwrite.c └── user.ld /.gitignore: -------------------------------------------------------------------------------- 1 | *.[oad] 2 | *~ 3 | *.iso 4 | *.txt 5 | 6 | kern 7 | asm.S 8 | obj 9 | 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | export CC := gcc 2 | export LD := ld 3 | export AR := ar 4 | export OBJCOPY := objcopy 5 | export OBJDUMP := objdump 6 | export ROOTDIR := $(shell pwd) 7 | export OBJDIR := obj 8 | 9 | SUBDIRS := fs kernel lib user 10 | LDFLAGS := -m elf_i386 11 | KHANDER := -I $(ROOTDIR)/include/ 12 | UHANDER := -I $(ROOTDIR)/include/ 13 | export INC := $(KHANDER) 14 | CFLAGE := -O1 -fno-builtin -fno-stack-protector -fno-omit-frame-pointer -nostdlib 15 | CFLAGE += -Wall -Wno-format -Wno-unused -Werror -gstabs -m32 -fno-tree-ch 16 | export UCFLAGS := $(UHANDER) $(CFLAGE) -DUSER 17 | export KCFLAGS := $(KHANDER) $(CFLAGE) -DKERNEL -DCONFIG_PAE -DCONFIG_DEBUG 18 | export KLDFLAGS := $(LDFLAGS) -T kernel.ld 19 | export ULDFLAGS := -T user.ld $(LDFLAGS) 20 | export V := @ 21 | 22 | export GCC_LIB := $(shell $(CC) $(CFLAGE) -print-libgcc-file-name) 23 | 24 | IMAGES := kenrel.iso 25 | BOCHS := bochs 26 | QEMU := qemu-system-i386 27 | QEMUOPTS := -m 60M -smp 4 28 | GRUB := grub-mkrescue 29 | IOSDIR := iso 30 | 31 | # 32 | OBJFILE := kernel/init kernel/mm kernel/char kernel/syscall\ 33 | kernel/trap kernel/block fs/minix1fs fs/rootfs fs/ramfs fs/ttyfs fs/pipefs fs kernel 34 | OBJFILE := $(patsubst %,%/*.S,$(OBJFILE)) $(patsubst %,%/*.c,$(OBJFILE)) 35 | OBJFILE := $(wildcard $(OBJFILE)) 36 | OBJFILE := $(patsubst %,$(ROOTDIR)/$(OBJDIR)/%,$(OBJFILE)) 37 | OBJFILE := $(patsubst %.S,%.c,$(OBJFILE)) 38 | OBJFILE := $(patsubst %.c,%.o,$(OBJFILE)) 39 | 40 | USEROBJ := $(ROOTDIR)/user/*.c 41 | USEROBJ := $(wildcard $(USEROBJ)) 42 | USEROBJ := $(patsubst %.c,%,$(USEROBJ)) 43 | USEROBJ := $(notdir $(USEROBJ)) 44 | USEROBJ := $(patsubst %,$(OBJDIR)/user/%.bin,$(USEROBJ)) 45 | 46 | FILE := $(ROOTDIR)/fs/*.sh 47 | FILE := $(wildcard $(FILE)) 48 | FILE := $(notdir $(FILE)) 49 | FILE := $(patsubst %.sh,$(OBJDIR)/fs/%.bin,$(FILE)) 50 | 51 | OBJFILE += obj/lib/string.o obj/lib/printfmt.o 52 | 53 | # Eliminate default suffix rules 54 | .SUFFIXES: 55 | # Delete target files if there is an error (or make is interrupted) 56 | .DELETE_ON_ERROR: 57 | 58 | 59 | all:$(SUBDIRS) $(ROOTDIR)/kern $(IMAGES) 60 | 61 | $(ROOTDIR)/kern:$(OBJFILE) $(USEROBJ) 62 | @echo $(LD) -o $@ $(KLDFLAGS) $(OBJFILE) $(USEROBJ) $(FILE) $(GCC_LIB) 63 | $(V)$(LD) -o $@ $(KLDFLAGS) $(OBJFILE) $(USEROBJ) $(FILE) $(GCC_LIB) 64 | $(V)cp kern $(IOSDIR)/boot/ 65 | $(V)$(GRUB) -o $(IMAGES) $(IOSDIR) 66 | $(V)$(OBJDUMP) -S kern > asm.S 67 | 68 | 69 | 70 | 71 | $(SUBDIRS):E 72 | $(V)make -s -C $@ 73 | E: 74 | 75 | $(IMAGES):$(ROOTDIR)/kern $(IOSDIR)/boot/grub/grub.cfg 76 | $(V)cp kern $(IOSDIR)/boot/ 77 | $(V)$(GRUB) -o $@ $(IOSDIR) 78 | 79 | boch:all 80 | $(V)$(BOCHS) -q -f bochsrc 81 | 82 | qemu:all 83 | $(V)$(QEMU) $(QEMUOPTS) $(IMAGES) 84 | 85 | .PHONY:clean 86 | clean: 87 | $(V)rm -rf $(OBJDIR) kern 88 | -------------------------------------------------------------------------------- /bochsrc: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # bochsrc.txt file for DLX Linux disk image. 3 | ############################################################### 4 | # how much memory the emulated machine will have 5 | megs: 60 6 | # filename of ROM images 7 | romimage: file=$BXSHARE/BIOS-bochs-legacy, address=0xffff0000 8 | vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest 9 | 10 | cpu: count=4 ,model=corei5_lynnfield_750 11 | 12 | 13 | 14 | #panic: action=ask 15 | ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 16 | ata0-master: type=disk, path=kenrel.iso, mode=flat, biosdetect=auto, translation=auto, model="Generic 1234" 17 | 18 | ata0-slave: type=disk, mode=flat, path=fs/image.img 19 | boot: disk 20 | 21 | #debug: action=ask, pci=report 22 | #log: /dev/tty 23 | 24 | keyboard: type=mf, serial_delay=200, paste_delay=100000 25 | #keyboard: keymap=gui/keymaps/x11-pc-de.map 26 | #keyboard: user_shortcut=ctrl-alt-del 27 | -------------------------------------------------------------------------------- /fs/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := minix1fs ramfs rootfs ttyfs pipefs 2 | 3 | 4 | CURDIR := $(notdir $(shell pwd)) 5 | 6 | objects := $(wildcard *.c) 7 | objects += $(wildcard *.S) 8 | objects := $(patsubst %.c,%.o,$(objects)) 9 | objects := $(patsubst %.S,%.o,$(objects)) 10 | objects := $(patsubst %,$(ROOTDIR)/$(OBJDIR)/$(CURDIR)/%,$(objects)) 11 | 12 | DEPS = $(patsubst %.c,$(ROOTDIR)/$(OBJDIR)/$(CURDIR)/%.d,$(wildcard *.c)) 13 | 14 | FILE := $(ROOTDIR)/fs/*.sh 15 | FILE := $(wildcard $(FILE)) 16 | FILE := $(notdir $(FILE)) 17 | FILE := $(patsubst %.sh,$(ROOTDIR)/$(OBJDIR)/fs/%.bin,$(FILE)) 18 | 19 | 20 | .PHONY: all 21 | all: $(SUBDIRS) $(DEPS) $(objects) $(FILE) 22 | 23 | $(DEPS):$(ROOTDIR)/$(OBJDIR)/$(CURDIR)/%.d:%.c 24 | @mkdir -p $(@D) 25 | $(V)$(CC) -MT $(patsubst %.d,%.o,$@) $(ROOTDIR)/$(CURDIR)/$< -ffreestanding -M $(INC) > $@ 26 | 27 | 28 | -include $(DEPS) 29 | 30 | $(ROOTDIR)/$(OBJDIR)/$(CURDIR)/%.bin:%.sh 31 | @echo $(OBJCOPY) -I binary -O elf32-i386 -B i386 $(notdir $^) $@ 32 | @cp $(notdir $^) $(ROOTDIR)/$(OBJDIR)/$(CURDIR) 33 | @cd $(ROOTDIR)/$(OBJDIR)/$(CURDIR) ; $(OBJCOPY) -I binary -O elf32-i386 -B i386 $(notdir $^) $@ 34 | 35 | $(ROOTDIR)/$(OBJDIR)/$(CURDIR)/%.o:%.c $(ROOTDIR)/$(OBJDIR)/$(CURDIR)/%.d 36 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 37 | @mkdir -p $(@D) 38 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 39 | 40 | $(ROOTDIR)/$(OBJDIR)/$(CURDIR)/%.o:%.S 41 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 42 | @mkdir -p $(@D) 43 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 44 | 45 | 46 | 47 | 48 | 49 | $(SUBDIRS):ECHO 50 | $(V)make -s -C $@ 51 | ECHO: 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /fs/dcache.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | #define MAX_DENTRY_INODE 1024 10 | 11 | static struct hlist_head dentry_hashtable[MAX_DENTRY_HASH]; 12 | STATIC_INIT_SPIN_LOCK(dcache_lock) 13 | struct dentry *root_dentry; 14 | 15 | 16 | struct dentry *d_alloc_root(struct inode * root_inode) 17 | { 18 | struct dentry *res = NULL; 19 | if (root_inode) { 20 | res = d_alloc(NULL, &(const struct qstr) { "/", 1}); 21 | if (res) { 22 | res->d_sb = root_inode->i_sb; 23 | res->d_parent = res; 24 | res->d_inode = root_inode; 25 | root_dentry = res; 26 | } 27 | } 28 | return res; 29 | } 30 | 31 | struct dentry* dentry_lookup(struct dentry *parent,struct qstr *qstr) 32 | { 33 | uint32_t h; 34 | struct hlist_head *hlist; 35 | struct dentry *d; 36 | h = hash(parent,qstr->name,qstr->len); 37 | hlist = &dentry_hashtable[h%MAX_DENTRY_HASH]; 38 | hlist_for_each_entry(d, hlist, d_hash){ 39 | if (!strncmp(d->d_name.name,qstr->name,qstr->len)) { 40 | return d; 41 | } 42 | } 43 | return NULL; 44 | } 45 | 46 | void dentry_insert(struct dentry *parent,struct dentry *dentry) 47 | { 48 | uint32_t h; 49 | struct hlist_head *hlist; 50 | h = hash(parent,dentry->d_name.name,dentry->d_name.len); 51 | hlist = &dentry_hashtable[h%MAX_DENTRY_HASH]; 52 | hlist_add_head(&dentry->d_hash, hlist); 53 | //printk("insert parent:%x name:%s len:%d\n",parent,dentry->d_name.name,dentry->d_name.len); 54 | } 55 | 56 | struct dentry * 57 | d_alloc(struct dentry * parent, const struct qstr *name) 58 | { 59 | struct dentry *dentry; 60 | char * str; 61 | dentry = kmalloc(sizeof(struct dentry)); 62 | if (!dentry) 63 | return NULL; 64 | dentry->d_name = *name; 65 | dentry->d_sb = NULL; 66 | dentry->d_parent = NULL; 67 | dentry->d_inode = NULL; 68 | dentry->d_op = NULL; 69 | dentry->d_mounted = 0; 70 | INIT_LIST_HEAD(&dentry->d_subdirs); 71 | INIT_HLIST_NODE(&dentry->d_hash); 72 | atomic_set(&dentry->d_count, 1); 73 | if (parent) { 74 | dentry->d_parent = dget(parent); 75 | dentry->d_sb = parent->d_sb; 76 | } 77 | return dentry; 78 | } 79 | 80 | int d_mountpoint(struct dentry *dentry) 81 | { 82 | return dentry->d_mounted; 83 | } 84 | -------------------------------------------------------------------------------- /fs/file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int get_empty_file(struct file **file) 7 | { 8 | int i,fd = -1; 9 | struct file *f; 10 | for (i = 0;i < MAX_FILE; i++) { 11 | if (!curtask->files->fd[i]) { 12 | fd = i; 13 | break; 14 | } 15 | } 16 | if (fd < 0) 17 | return -EMFILE; 18 | 19 | f = alloc_file(); 20 | if (!f) 21 | return -ENOMEM; 22 | *file = f; 23 | curtask->files->fd[fd] = f; 24 | return fd; 25 | } 26 | 27 | int get_unused_fd() 28 | { 29 | int i,fd = -1; 30 | for (fd = 0;fd < MAX_FILE; fd++) { 31 | if (!curtask->files->fd[fd]) { 32 | break; 33 | } 34 | } 35 | if (fd >= MAX_FILE) 36 | return -EMFILE; 37 | else 38 | return fd; 39 | } 40 | 41 | int find_file(int fd,struct file **file,int mode) 42 | { 43 | if (curtask->files->fd[fd]) { 44 | *file = curtask->files->fd[fd]; 45 | } else { 46 | *file = NULL; 47 | return -EBADF; 48 | } 49 | return 0; 50 | } 51 | 52 | void deref_file(int fd) 53 | { 54 | struct file *file = curtask->files->fd[fd]; 55 | if (!file) 56 | return; 57 | 58 | if (file->f_op && file->f_op->flush) 59 | file->f_op->flush(file); 60 | 61 | file->f_count--; 62 | if (!file->f_count) { 63 | if (file->f_op && file->f_op->release) 64 | file->f_op->release(NULL,file); 65 | free_file(file); 66 | } 67 | curtask->files->fd[fd] = NULL; 68 | } 69 | 70 | void free_file(struct file *file) 71 | { 72 | if (file) 73 | kfree(file); 74 | } 75 | 76 | 77 | struct file *alloc_file() 78 | { 79 | struct file *file; 80 | 81 | file = kmalloc(sizeof(struct file)); 82 | if (!file) 83 | return NULL; 84 | memset(file,0,sizeof(struct file)); 85 | return file; 86 | } 87 | -------------------------------------------------------------------------------- /fs/file_system.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct file_system_type * find_filesystem(const char *, unsigned ); 9 | struct super_block *find_super_block(struct file_system_type *,int); 10 | 11 | struct list_head file_system = LIST_HEAD_INIT(file_system); 12 | 13 | STATIC_INIT_SPIN_LOCK(file_systems_lock); 14 | 15 | extern struct file_system_type root_fs; 16 | extern struct file_system_type minix_fs; 17 | extern struct file_system_type ramfs_fs; 18 | extern struct file_system_type tty_fs; 19 | extern struct file_system_type pipe_fs; 20 | 21 | struct file_system_type *filesystem [] = 22 | { 23 | &root_fs, 24 | &ramfs_fs, 25 | &tty_fs, 26 | &pipe_fs, 27 | NULL 28 | }; 29 | 30 | void filesystem_init() 31 | { 32 | struct file_system_type **fs = filesystem; 33 | while (*fs) { 34 | register_filesystem(*fs); 35 | fs++; 36 | } 37 | } 38 | 39 | int register_filesystem(struct file_system_type * fs) 40 | { 41 | int res = 0; 42 | 43 | if (!list_empty(&fs->next)) 44 | return -EBUSY; 45 | 46 | spin_lock(&file_systems_lock); 47 | 48 | if (find_filesystem(fs->name, strlen(fs->name))) { 49 | res = -EBUSY; 50 | } else { 51 | INIT_LIST_HEAD(&fs->fs_supers); 52 | INIT_LIST_HEAD(&fs->next); 53 | list_add(&fs->next,&file_system); 54 | res = fs->fs_init(NULL); 55 | } 56 | spin_unlock(&file_systems_lock); //解锁 57 | return res; 58 | } 59 | 60 | 61 | struct file_system_type * 62 | find_filesystem(const char *name, unsigned len) 63 | { 64 | struct file_system_type *fs; 65 | list_for_each_entry(fs, &file_system, next) { 66 | if (strlen(fs->name) == len && 67 | strncmp(fs->name, name, len) == 0) 68 | return fs; 69 | } 70 | 71 | return NULL; 72 | } 73 | 74 | 75 | struct super_block * 76 | find_super_block(struct file_system_type *fs,int dev) 77 | { 78 | struct super_block *sb; 79 | assert(fs); 80 | list_for_each_entry(sb, &fs->fs_supers, s_list) { 81 | if (sb->s_dev == dev) 82 | return sb; 83 | } 84 | return NULL; 85 | } 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /fs/inode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | #define MAX_HASH_INODE 1024 11 | #define inode_hashfn(dev,num) (((uint32_t)((dev)^(num)))%MAX_HASH_INODE) 12 | #define inode_hash(dev,num) inode_table[inode_hashfn(dev,num)] 13 | 14 | 15 | static struct dentry* find_dentry(struct dentry *,char *,int); 16 | STATIC_INIT_SPIN_LOCK(inode_lock); 17 | 18 | 19 | struct hlist_head inode_table[MAX_HASH_INODE]; 20 | 21 | static struct inode *alloc_inode(struct super_block *sb) 22 | { 23 | struct inode *inode; 24 | 25 | if (sb->s_op->alloc_inode) { 26 | inode = sb->s_op->alloc_inode(sb); 27 | } else { 28 | inode = kmalloc(sizeof(struct inode)); 29 | } 30 | 31 | if (inode) { 32 | inode->i_sb = sb; 33 | inode->i_dev = sb->s_dev; 34 | inode->i_op = &empty_iops; 35 | inode->i_inode = NULL; 36 | inode->i_mode = 0; 37 | atomic_set(&inode->i_count, 1); 38 | INIT_HLIST_NODE(&inode->i_hash); 39 | } 40 | return inode; 41 | } 42 | 43 | 44 | struct inode *new_inode(struct super_block *sb) 45 | { 46 | static uint32_t last_ino; 47 | struct inode * inode; 48 | 49 | inode = alloc_inode(sb); 50 | if (inode) { 51 | spin_lock(&inode_lock); 52 | //list_add(&inode->i_list, &inode_in_use); 53 | inode->i_num = ++last_ino; 54 | inode->i_state = 0; 55 | spin_unlock(&inode_lock); 56 | } 57 | return inode; 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /fs/lorem.sh: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur 2 | adipisicing elit, sed do eiusmod tempor 3 | incididunt ut labore et dolore magna 4 | aliqua. Ut enim ad minim veniam, quis 5 | nostrud exercitation ullamco laboris 6 | nisi ut aliquip ex ea commodo consequat. 7 | Duis aute irure dolor in reprehenderit 8 | in voluptate velit esse cillum dolore eu 9 | fugiat nulla pariatur. Excepteur sint 10 | occaecat cupidatat non proident, sunt in 11 | culpa qui officia deserunt mollit anim 12 | id est laborum. 13 | -------------------------------------------------------------------------------- /fs/minix1fs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CURDIR := $(notdir $(shell pwd)) 3 | 4 | objects := $(wildcard *.c) 5 | objects += $(wildcard *.S) 6 | objects := $(patsubst %.c,%.o,$(objects)) 7 | objects := $(patsubst %.S,%.o,$(objects)) 8 | objects := $(patsubst %,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%,$(objects)) 9 | 10 | DEPS = $(patsubst %.c,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d,$(wildcard *.c)) 11 | 12 | 13 | 14 | 15 | .PHONY: all 16 | all:$(DEPS) $(objects) 17 | 18 | $(DEPS):$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d:%.c 19 | @mkdir -p $(@D) 20 | $(CC) -MT $(patsubst %.d,%.o,$@) $(ROOTDIR)/fs/$(CURDIR)/$< -ffreestanding -M $(INC) > $@ 21 | 22 | 23 | -include $(DEPS) 24 | 25 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.c $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d 26 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 27 | @mkdir -p $(@D) 28 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 29 | 30 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.S 31 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 32 | @mkdir -p $(@D) 33 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /fs/minix1fs/minix_bitmap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int new_block(struct super_block *sb) 7 | { 8 | return 0; 9 | } 10 | 11 | void free_inode(struct minix_superblock* msb) 12 | { 13 | 14 | } 15 | 16 | void free_block(int dev, int block) 17 | { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /fs/minix1fs/minix_dcache.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static uint32_t minix_dentry_hash(const struct dentry *, const char *,int); 5 | 6 | 7 | 8 | struct dentry_operations minix_dentry_op = 9 | { 10 | .d_hash = minix_dentry_hash 11 | }; 12 | 13 | 14 | 15 | 16 | static uint32_t 17 | minix_dentry_hash(const struct dentry *parent,const char* str,int len) 18 | { 19 | int hash = _hash(str,len); 20 | hash += ((uint32_t) parent ^ GOLDEN_RATIO_PRIME); 21 | hash = hash ^ (hash ^ GOLDEN_RATIO_PRIME); 22 | return hash; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /fs/minix1fs/minix_fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | static struct super_block *get_minix_super(struct file_system_type *,int); 8 | static int minix_init(void*); 9 | 10 | struct file_system_type minix_fs = 11 | { 12 | .name = "minix1", 13 | //.get_super = get_minix_super, 14 | .fs_init = minix_init, 15 | .next = LIST_HEAD_INIT(minix_fs.next), 16 | .fs_supers = LIST_HEAD_INIT(minix_fs.fs_supers), 17 | }; 18 | 19 | static int minix_init(void *v) 20 | { 21 | printk("registering %s file system!\n",minix_fs.name); 22 | return 0; 23 | } 24 | 25 | static struct super_block * 26 | get_minix_super(struct file_system_type *fs,int dev) 27 | { 28 | struct minix_superblock* msb = NULL; 29 | struct buffer_head *buf = NULL; 30 | struct super_block* sb; 31 | 32 | return NULL; 33 | } 34 | -------------------------------------------------------------------------------- /fs/minix1fs/minix_inode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | #define MIN(a,b) (((a)<(b))?(a):(b)) 12 | #define MAX(a,b) (((a)>(b))?(a):(b)) 13 | 14 | static int minix_file_write(struct file *,char* , int ,int ); 15 | static int minix_file_read(struct file *,char* , int ,int ); 16 | static int minix_file_open(struct inode *,struct file *); 17 | 18 | static struct dentry* minix_lookup(struct inode *dir,struct dentry *dentry,struct nameidata* nd); 19 | static int _bmap(struct inode *,int); 20 | 21 | static void put_fs_byte(char c,char* p) 22 | { 23 | *p = c; 24 | } 25 | 26 | 27 | struct inode_operations minix_inode_op = 28 | { 29 | 30 | }; 31 | 32 | struct file_operations minix_file_op = 33 | { 34 | .read = minix_file_read, 35 | .open = minix_file_open, 36 | .write = minix_file_write, 37 | }; 38 | 39 | 40 | 41 | struct dentry *minix_lookup(struct inode *dir, 42 | struct dentry *dentry,struct nameidata* nd) 43 | { 44 | return NULL; 45 | } 46 | 47 | static int minix_file_write(struct file *file, 48 | char* buf, int count,int offset) 49 | { 50 | return 0; 51 | } 52 | 53 | static int minix_file_read(struct file *file, 54 | char* buf, int count,int offset) 55 | { 56 | int left,chars,nr; 57 | struct buffer_head * bh; 58 | struct inode *inode; 59 | inode = file->f_inode; 60 | 61 | 62 | if ((left = count) <= 0) 63 | return 0; 64 | 65 | while (left) { 66 | nr = _bmap(inode,(file->f_pos)/BLOCK_SIZE); 67 | if (nr) { 68 | bh = buffer_read(inode->i_dev,nr); 69 | if (!bh) 70 | break; 71 | } else 72 | bh = NULL; 73 | 74 | nr = file->f_pos % BLOCK_SIZE; 75 | chars = MIN( BLOCK_SIZE-nr , left ); 76 | 77 | file->f_pos += chars; 78 | left -= chars; 79 | 80 | if (bh) { 81 | char *p = nr + bh->b_data; 82 | while (chars-->0) 83 | put_fs_byte(*(p++),buf++); 84 | //brelse(bh); 85 | } else { 86 | while (chars-->0) 87 | put_fs_byte(0,buf++); 88 | } 89 | 90 | } 91 | return (count-left)?(count-left):-ERROR; 92 | } 93 | 94 | static int minix_file_open(struct inode *inode,struct file *file) 95 | { 96 | printk("minix opened!\n"); 97 | return 0; 98 | } 99 | 100 | static int _bmap(struct inode *inode,int block) 101 | { 102 | struct minix1_inode *m; 103 | 104 | if (inode && inode->i_inode) 105 | m = inode->i_inode; 106 | else 107 | panic("inode!"); 108 | 109 | if (block<0) 110 | panic("_bmap: block<0"); 111 | if (block >= 7) 112 | panic("_bmap: block>big"); 113 | 114 | if (block<7) { 115 | return m->i_zone[block]; 116 | } 117 | return 0; 118 | } 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /fs/minix1fs/minix_super.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | static void destroy_minix_inode(struct inode *); 8 | static struct inode *alloc_minix_inode(struct super_block *); 9 | static int read_minix_inode(struct inode *); 10 | static int read_minix_super(struct super_block *,void*,int); 11 | 12 | struct super_operations minix_super_op = 13 | { 14 | .alloc_inode = alloc_minix_inode, 15 | .destroy_inode = destroy_minix_inode, 16 | .read_inode = read_minix_inode, 17 | .read_super = read_minix_super, 18 | }; 19 | 20 | static int read_minix_super(struct super_block *sb,void* data,int slient) 21 | { 22 | struct minix_superblock* msb = NULL; 23 | struct buffer_head *buf = NULL; 24 | 25 | buf = buffer_read(sb->s_dev,1); 26 | assert(buf); 27 | 28 | msb = (struct minix_superblock *)buf->b_data; 29 | 30 | if (msb->s_magic != 0x138F) 31 | return -1; 32 | 33 | *(struct minix_superblock *)sb->s_super = *msb; 34 | 35 | return 0; 36 | } 37 | 38 | static int read_minix_inode(struct inode *inode) 39 | { 40 | int block; 41 | assert(inode); 42 | struct super_block *sb = NULL; 43 | struct minix_superblock *msb = NULL; 44 | struct minix1_inode *minode; 45 | struct buffer_head * buf; 46 | 47 | sb = inode->i_sb; 48 | assert(sb); 49 | msb = (struct minix_superblock *)sb->s_super; 50 | assert(msb); 51 | minode = (struct minix1_inode *)inode->i_inode; 52 | assert(minode); 53 | 54 | block = 2 + msb->s_imap_blocks + msb->s_zmap_blocks + inode->i_num / MINIX1_INODES_PER_BLOCK; 55 | 56 | if (!(buf = buffer_read(inode->i_dev,block))) 57 | panic("unable to read i-node block"); 58 | 59 | *(struct minix1_inode *)inode->i_inode = 60 | ((struct minix1_inode *)buf->b_data)[inode->i_num % MINIX1_INODES_PER_BLOCK]; 61 | return 0; 62 | } 63 | 64 | static void 65 | destroy_minix_inode(struct inode *inode) 66 | { 67 | 68 | } 69 | 70 | static struct inode * 71 | alloc_minix_inode(struct super_block *sb) 72 | { 73 | assert(sb); 74 | assert(sb->s_super); 75 | 76 | struct minix_superblock *msb = NULL; 77 | struct inode *inode = NULL; 78 | msb = (struct minix_superblock *)sb->s_super; 79 | 80 | return inode; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /fs/pipefs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CURDIR := $(notdir $(shell pwd)) 3 | 4 | objects := $(wildcard *.c) 5 | objects += $(wildcard *.S) 6 | objects := $(patsubst %.c,%.o,$(objects)) 7 | objects := $(patsubst %.S,%.o,$(objects)) 8 | objects := $(patsubst %,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%,$(objects)) 9 | 10 | DEPS = $(patsubst %.c,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d,$(wildcard *.c)) 11 | 12 | 13 | 14 | 15 | .PHONY: all 16 | all:$(DEPS) $(objects) 17 | 18 | $(DEPS):$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d:%.c 19 | @mkdir -p $(@D) 20 | $(CC) -MT $(patsubst %.d,%.o,$@) $(ROOTDIR)/fs/$(CURDIR)/$< -ffreestanding -M $(INC) > $@ 21 | 22 | 23 | -include $(DEPS) 24 | 25 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.c $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d 26 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 27 | @mkdir -p $(@D) 28 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 29 | 30 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.S 31 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 32 | @mkdir -p $(@D) 33 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /fs/pipefs/pipe_fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static int pipefs_init(void*); 7 | static struct super_block *pipefs_get_super(struct file_system_type *,int ,void *); 8 | 9 | struct vfsmount *pipe_mnt; 10 | 11 | struct file_system_type pipe_fs = 12 | { 13 | .name = "pipefs", 14 | .get_super = pipefs_get_super, 15 | .fs_init = pipefs_init, 16 | .next = LIST_HEAD_INIT(pipe_fs.next), 17 | .fs_supers = LIST_HEAD_INIT(pipe_fs.fs_supers), 18 | }; 19 | 20 | 21 | static int pipefs_init(void *data) 22 | { 23 | struct super_block *sb; 24 | struct vfsmount *mnt; 25 | int res; 26 | 27 | printk("registering %s file system!\n",pipe_fs.name); 28 | 29 | mnt = alloc_vfsmnt(pipe_fs.name); 30 | assert(mnt); 31 | pipe_mnt = mnt; 32 | sb = pipe_fs.get_super(&pipe_fs,0,NULL); 33 | 34 | list_add(&sb->s_list,&pipe_fs.fs_supers); 35 | res = sb->s_op->read_super(sb,mnt,0); 36 | return 0; 37 | } 38 | 39 | static struct super_block * 40 | pipefs_get_super(struct file_system_type *fs_type,int dev,void *data) 41 | { 42 | struct super_block *s; 43 | s = find_super_block(fs_type,dev); 44 | if (s) 45 | return s; 46 | s = new_sb(fs_type,dev,data); 47 | s->s_op = &pipefs_super_op; 48 | s->s_blocksize = PAGE_SIZE; 49 | s->s_magic = PIPEFS_MAGIC; 50 | return s; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /fs/pipefs/pipe_inode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | static int pipefs_file_read(struct file *,char*,int,int); 10 | static int pipefs_file_write(struct file *,char*,int,int); 11 | static int pipefs_file_open(struct inode *,struct file *); 12 | static int pipefs_file_release(struct inode *inode,struct file *); 13 | static int pipefs_file_flush(struct file *); 14 | 15 | 16 | static int pipe_new(struct inode *); 17 | static struct pipe_inode_info *get_pipe_info(void); 18 | 19 | struct inode_operations pipefs_inode_op = 20 | { 21 | .lookup = NULL, 22 | }; 23 | 24 | struct file_operations pipefs_file_op = 25 | { 26 | .read = pipefs_file_read, 27 | .open = pipefs_file_open, 28 | .write = pipefs_file_write, 29 | .release = pipefs_file_release, 30 | .flush = pipefs_file_flush, 31 | }; 32 | 33 | static int pipefs_file_flush(struct file *file) 34 | { 35 | struct inode *inode; 36 | struct pipe_inode_info *info; 37 | 38 | inode = file->f_inode; 39 | info = (struct pipe_inode_info *)inode->i_pipe; 40 | 41 | switch (file->f_flags & O_ACCMODE) { 42 | case O_RDONLY: 43 | info->p_reader--; 44 | break; 45 | case O_WRONLY: 46 | info->p_writer++; 47 | break; 48 | } 49 | return 0; 50 | } 51 | 52 | static int pipefs_file_release(struct inode *inode,struct file *file) 53 | { 54 | printk("release! pipe\n"); 55 | return 0; 56 | } 57 | 58 | static int pipefs_file_write(struct file *file, 59 | char* buf, int count,int offset) 60 | { 61 | struct inode *inode; 62 | struct pipe_inode_info *info; 63 | int i; 64 | char *start; 65 | 66 | inode = file->f_inode; 67 | info = (struct pipe_inode_info *)inode->i_pipe; 68 | 69 | start = (char*)page2virt(info->p_page); 70 | 71 | 72 | for (i = 0; i < count; i++) { 73 | 74 | if (info->p_wpos >= info->p_rpos + PAGE_SIZE) { 75 | if (i >= 0) 76 | return i; 77 | if (info->p_reader == 0) { 78 | return 0; 79 | } 80 | } 81 | 82 | start[info->p_wpos % PAGE_SIZE] = buf[i]; 83 | info->p_wpos++; 84 | } 85 | 86 | return i; 87 | } 88 | 89 | static int pipefs_file_read(struct file *file, 90 | char* buf, int count,int offset) 91 | { 92 | struct inode *inode; 93 | struct pipe_inode_info *info; 94 | char *start; 95 | int i; 96 | 97 | inode = file->f_inode; 98 | info = (struct pipe_inode_info *)inode->i_pipe; 99 | start = (char*)page2virt(info->p_page); 100 | 101 | 102 | for (i = 0; i < count; i++) { 103 | 104 | if (info->p_rpos == info->p_wpos) { 105 | if (i > 0) 106 | return i; 107 | if (info->p_writer == 0) { 108 | return 0; 109 | } 110 | } 111 | buf[i] = start[info->p_rpos % PAGE_SIZE]; 112 | info->p_rpos++; 113 | } 114 | 115 | return i; 116 | } 117 | 118 | static int pipefs_file_open(struct inode *inode,struct file *file) 119 | { 120 | printk("pipe opened!\n"); 121 | return 0; 122 | } 123 | 124 | 125 | -------------------------------------------------------------------------------- /fs/pipefs/pipe_super.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | static int pipefs_read_super(struct super_block *,void*,int); 10 | extern struct vfsmount *root_vfsmnt; 11 | struct super_operations pipefs_super_op = 12 | { 13 | .read_super = pipefs_read_super, 14 | }; 15 | 16 | 17 | 18 | static int pipefs_read_super(struct super_block *sb, 19 | void* data,int slient) 20 | { 21 | struct dentry *root; 22 | struct inode *inode = NULL; 23 | struct vfsmount* mnt = (struct vfsmount*)data; 24 | 25 | inode = simple_get_inode(sb, S_IFDIR, sb->s_dev); 26 | 27 | assert(inode); 28 | root = d_alloc(root_vfsmnt->mnt_mountpoint,&(const struct qstr){"pipefs",6}); 29 | assert(root); 30 | 31 | 32 | mnt->mnt_sb = sb; 33 | mnt->mnt_mountpoint = root; 34 | mnt->mnt_root = root_vfsmnt->mnt_mountpoint; 35 | mnt->mnt_parent = root_vfsmnt; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /fs/ramfs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CURDIR := $(notdir $(shell pwd)) 3 | 4 | objects := $(wildcard *.c) 5 | objects += $(wildcard *.S) 6 | objects := $(patsubst %.c,%.o,$(objects)) 7 | objects := $(patsubst %.S,%.o,$(objects)) 8 | objects := $(patsubst %,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%,$(objects)) 9 | 10 | DEPS = $(patsubst %.c,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d,$(wildcard *.c)) 11 | 12 | 13 | 14 | 15 | .PHONY: all 16 | all:$(DEPS) $(objects) 17 | 18 | $(DEPS):$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d:%.c 19 | @mkdir -p $(@D) 20 | $(CC) -MT $(patsubst %.d,%.o,$@) $(ROOTDIR)/fs/$(CURDIR)/$< -ffreestanding -M $(INC) > $@ 21 | 22 | 23 | -include $(DEPS) 24 | 25 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.c $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d 26 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 27 | @mkdir -p $(@D) 28 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 29 | 30 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.S 31 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 32 | @mkdir -p $(@D) 33 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /fs/ramfs/ram_fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | static int ramfs_init(void*); 10 | static void _create_file(struct inode *inode,uint8_t *start,uint8_t *end); 11 | static void create_file(struct dentry *parent); 12 | 13 | struct file_system_type ramfs_fs = 14 | { 15 | .name = "ramfs", 16 | //.get_super = ramfs_get_super, 17 | .fs_init = ramfs_init, 18 | .next = LIST_HEAD_INIT(ramfs_fs.next), 19 | .fs_supers = LIST_HEAD_INIT(ramfs_fs.fs_supers), 20 | }; 21 | 22 | static int ramfs_init(void* data) 23 | { 24 | printk("registering %s file system!\n",ramfs_fs.name); 25 | 26 | int res; 27 | struct super_block *sb; 28 | struct dentry *parent; 29 | struct qstr name; 30 | 31 | create_file(root_dentry); 32 | 33 | return 0; 34 | } 35 | 36 | static void _create_file(struct inode *inode,uint8_t *start,uint8_t *end) 37 | { 38 | struct ram_file *ram; 39 | ram = kmalloc(sizeof(struct ram_file)); 40 | assert(ram); 41 | 42 | inode->i_inode = ram; 43 | ram->start = start; 44 | ram->size = end - ram->start; 45 | } 46 | 47 | #define CREATE(name,x,p) \ 48 | do { \ 49 | struct inode *inode; \ 50 | extern uint8_t TASK_PASTE3(_binary_, x, _start)[]; \ 51 | extern uint8_t TASK_PASTE3(_binary_, x, _end)[]; \ 52 | inode = create_node(p, &(struct qstr) { name, strlen(name)},S_IFREG, \ 53 | &ramfs_file_operations,&ramfs_dir_inode_operations); \ 54 | _create_file(inode,TASK_PASTE3(_binary_, x, _start),TASK_PASTE3(_binary_, x, _end));\ 55 | } while (0) 56 | 57 | static void create_file(struct dentry *parent) 58 | { 59 | CREATE("hello",hello,parent); 60 | CREATE("forktree",forktree,parent); 61 | CREATE("sh",sh,parent); 62 | CREATE("echo",echo,parent); 63 | CREATE("num",num,parent); 64 | CREATE("cat",cat,parent); 65 | CREATE("shell_sh",shell_sh,parent); 66 | CREATE("lorem_sh",lorem_sh,parent); 67 | CREATE("script_sh",script_sh,parent); 68 | } 69 | -------------------------------------------------------------------------------- /fs/ramfs/ramfs_inode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | 12 | static struct super_operations ramfs_ops; 13 | 14 | 15 | static int ramfs_create(struct inode *,struct dentry *, int , struct nameidata *); 16 | static int ramfs_mknod(struct inode *, struct dentry *, int , int); 17 | static int ramfs_mkdir(struct inode *, struct dentry * , int); 18 | static int ramfs_file_write(struct file *,char* , int ,int ); 19 | static int ramfs_file_read(struct file *,char* , int ,int ); 20 | static int ramfs_file_open(struct inode *,struct file *); 21 | 22 | 23 | struct inode_operations ramfs_dir_inode_operations = 24 | { 25 | .create = ramfs_create, 26 | .lookup = simple_dir_inode_lookup, 27 | .mkdir = ramfs_mkdir, 28 | //.rmdir = simple_rmdir, 29 | .mknod = ramfs_mknod, 30 | //.rename = simple_rename, 31 | }; 32 | 33 | struct inode_operations ramfs_file_inode_operations = 34 | { 35 | .create = ramfs_create, 36 | .lookup = simple_file_inode_lookup, 37 | .mkdir = ramfs_mkdir, 38 | //.rmdir = simple_rmdir, 39 | .mknod = ramfs_mknod, 40 | //.rename = simple_rename, 41 | 42 | }; 43 | 44 | static struct file_operations ramfs_dir_operations = 45 | { 46 | 47 | }; 48 | 49 | struct file_operations ramfs_file_operations = 50 | { 51 | .read = ramfs_file_read, 52 | .open = ramfs_file_open, 53 | .write = ramfs_file_write, 54 | }; 55 | 56 | static int ramfs_file_open(struct inode *inode,struct file *file) 57 | { 58 | printk("open ram files\n"); 59 | return 0; 60 | } 61 | 62 | static int ramfs_file_read(struct file *file, 63 | char* buf, int count,int offset) 64 | { 65 | struct ram_file *ram; 66 | struct inode *inode; 67 | char *binary; 68 | int curpos; 69 | 70 | inode = file->f_inode; 71 | assert(inode); 72 | 73 | ram = (struct ram_file *)inode->i_inode; 74 | assert(ram); 75 | 76 | assert(file); 77 | 78 | assert(ram->start); 79 | if (file->f_pos >= ram->size) 80 | return 0; 81 | 82 | if (file->f_pos + count >= ram->size) { 83 | count = ram->size - file->f_pos; 84 | } 85 | memcpy(buf,ram->start + file->f_pos,count); 86 | file->f_pos += count; 87 | 88 | return count; 89 | } 90 | static int ramfs_file_write(struct file *file, 91 | char* buf, int count,int offset) 92 | { 93 | return 0; 94 | } 95 | 96 | 97 | 98 | static int 99 | ramfs_mknod(struct inode *dir, 100 | struct dentry *dentry, int mode, int dev) 101 | { 102 | struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev); 103 | int error = -ENOSPC; 104 | 105 | if (inode) { 106 | dentry->d_inode = inode; 107 | atomic_set(&dentry->d_count,1); 108 | error = 0; 109 | } 110 | return error; 111 | } 112 | 113 | static int 114 | ramfs_create(struct inode *dir, 115 | struct dentry *dentry, int mode, 116 | struct nameidata *nd) 117 | { 118 | return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); 119 | } 120 | 121 | static int 122 | ramfs_mkdir(struct inode *dir, 123 | struct dentry * dentry, int mode) 124 | { 125 | int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); 126 | if (!retval) 127 | dir->i_nlink++; 128 | return retval; 129 | } 130 | 131 | struct inode * 132 | ramfs_get_inode(struct super_block *sb, 133 | int mode, int dev) 134 | { 135 | struct inode *inode = new_inode(sb); 136 | 137 | if (inode) { 138 | switch (mode & S_IFMT) { 139 | case S_IFREG: 140 | inode->i_op = &simple_file_inode_operations; 141 | inode->i_fop = &simple_file_operations; 142 | break; 143 | case S_IFDIR: 144 | inode->i_op = &ramfs_dir_inode_operations; 145 | inode->i_fop = &simple_dir_operations; 146 | break; 147 | } 148 | inode->i_mode = mode; 149 | inode->i_sb = sb; 150 | 151 | } 152 | return inode; 153 | } 154 | -------------------------------------------------------------------------------- /fs/ramfs/ramfs_super.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | static int ramfs_read_super(struct super_block * , void * , int ); 7 | 8 | static struct super_operations ramfs_super_ops = 9 | { 10 | .read_super = ramfs_read_super 11 | }; 12 | 13 | static int 14 | ramfs_read_super(struct super_block * sb, 15 | void * data, int silent) 16 | { 17 | 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /fs/rootfs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CURDIR := $(notdir $(shell pwd)) 3 | 4 | objects := $(wildcard *.c) 5 | objects += $(wildcard *.S) 6 | objects := $(patsubst %.c,%.o,$(objects)) 7 | objects := $(patsubst %.S,%.o,$(objects)) 8 | objects := $(patsubst %,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%,$(objects)) 9 | 10 | DEPS = $(patsubst %.c,$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d,$(wildcard *.c)) 11 | 12 | 13 | 14 | 15 | .PHONY: all 16 | all:$(DEPS) $(objects) 17 | 18 | $(DEPS):$(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d:%.c 19 | @mkdir -p $(@D) 20 | $(CC) -MT $(patsubst %.d,%.o,$@) $(ROOTDIR)/fs/$(CURDIR)/$< -ffreestanding -M $(INC) > $@ 21 | 22 | 23 | -include $(DEPS) 24 | 25 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.c $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.d 26 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 27 | @mkdir -p $(@D) 28 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 29 | 30 | $(ROOTDIR)/$(OBJDIR)/fs/$(CURDIR)/%.o:%.S 31 | @echo $(CC) $(KCFLAGS) -c $< -o $@ 32 | @mkdir -p $(@D) 33 | $(V)$(CC) $(KCFLAGS) -c $< -o $@ 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /fs/rootfs/root_fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | extern struct vfsmount *root_vfsmnt; 8 | static int rootfs_init(void*); 9 | static struct super_block *rootfs_get_super(struct file_system_type *,int ,void *); 10 | 11 | struct file_system_type root_fs = 12 | { 13 | .name = "rootfs", 14 | .get_super = rootfs_get_super, 15 | .fs_init = rootfs_init, 16 | .next = LIST_HEAD_INIT(root_fs.next), 17 | .fs_supers = LIST_HEAD_INIT(root_fs.fs_supers), 18 | }; 19 | 20 | static int rootfs_init(void *v) 21 | { 22 | printk("registering %s file system!\n",root_fs.name); 23 | 24 | struct super_block *sb; 25 | struct vfsmount *mnt; 26 | int res; 27 | mnt = alloc_vfsmnt(root_fs.name); 28 | assert(mnt); 29 | root_vfsmnt = mnt; 30 | sb = root_fs.get_super(&root_fs,0,NULL); 31 | 32 | assert(sb); 33 | 34 | list_add(&sb->s_list,&root_fs.fs_supers); 35 | res = sb->s_op->read_super(sb,mnt,0); 36 | assert(res == 0); 37 | 38 | print_dentry(root_dentry); 39 | 40 | create_node(root_dentry, &(struct qstr) { "dev", 3},S_IFDIR,NULL,NULL); 41 | return 0; 42 | } 43 | 44 | static struct super_block * 45 | rootfs_get_super(struct file_system_type *fs_type,int dev,void *data) 46 | { 47 | struct super_block *s; 48 | s = find_super_block(fs_type,dev); 49 | if (s) 50 | return s; 51 | s = new_sb(fs_type,dev,data); 52 | s->s_op = &root_super_op; 53 | s->s_blocksize = PAGE_SIZE; 54 | s->s_magic = ROOTFS_MAGIC; 55 | return s; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /fs/rootfs/root_inode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | struct dentry *rootfs_lookup(struct inode *,struct dentry *, struct nameidata*); 12 | static int rootfs_file_read(struct file *,char* , int ,int ); 13 | static int rootfs_inode_create(struct inode *,struct dentry *, int, struct nameidata*); 14 | 15 | struct inode_operations rootfs_inode_op = 16 | { 17 | .create = rootfs_inode_create, 18 | .lookup = rootfs_lookup, 19 | }; 20 | 21 | struct file_operations rootfs_file_op = 22 | { 23 | .read = rootfs_file_read, 24 | }; 25 | 26 | static int rootfs_inode_create(struct inode *dir, 27 | struct dentry *dentry, int mode, struct nameidata* nd) 28 | { 29 | return 0; 30 | } 31 | 32 | struct dentry *rootfs_lookup(struct inode *dir, 33 | struct dentry *dentry,struct nameidata* nd) 34 | { 35 | return NULL; 36 | } 37 | 38 | static int rootfs_file_read(struct file *file, 39 | char* buf, int count,int offset) 40 | { 41 | int i; 42 | printk("This is rootfs!!!!! Are you kidding me?\n"); 43 | for (i = 0; i < count; i++) { 44 | buf[i] = 'c'; 45 | } 46 | return i; 47 | } 48 | -------------------------------------------------------------------------------- /fs/rootfs/root_super.c: -------------------------------------------------------------------------------- 1 | #include 2 | //#include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | static int root_read_super(struct super_block *,void*,int); 10 | 11 | struct super_operations root_super_op = 12 | { 13 | .read_super = root_read_super, 14 | }; 15 | 16 | 17 | static int root_read_super(struct super_block *sb, 18 | void* data,int slient) 19 | { 20 | struct dentry *root; 21 | struct inode *inode = NULL; 22 | struct vfsmount* mnt = (struct vfsmount*)data; 23 | 24 | inode = simple_get_inode(sb, S_IFDIR, sb->s_dev); 25 | 26 | printk("alloc root inode 0x%x mode:%o ",inode,inode->i_mode); 27 | assert(inode); 28 | root = d_alloc_root(inode); 29 | assert(root); 30 | 31 | printk("alloc root dentry 0x%x ",root); 32 | 33 | mnt->mnt_sb = sb; 34 | mnt->mnt_mountpoint = root; 35 | mnt->mnt_root = root; 36 | mnt->mnt_parent = mnt; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /fs/script.sh: -------------------------------------------------------------------------------- 1 | echo This is from the script. 2 | cat lorem | num | cat 3 | echo These are my file descriptors. 4 | echo This is the end of the script. 5 | -------------------------------------------------------------------------------- /fs/shell.sh: -------------------------------------------------------------------------------- 1 | echo hello world | cat 2 | cat lorem 3 | cat lorem |num 4 | cat lorem |num |num |num |num |num 5 | lsfd -1 6 | cat script 7 | sh