From 2445034e430fb47c883895942016ea201e11bf2d Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 20 Dec 2004 22:00:00 -0500 Subject: [PATCH] Import backup from 2004-12-20 --- Makefile | 18 ++++- kernel/Makefile | 3 +- kernel/block/ramdisk.c | 60 +++++++------- kernel/fs/devfs.c | 11 ++- kernel/fs/devfs.h | 4 +- kernel/fs/devices.c | 3 +- kernel/fs/devices.h | 1 + kernel/fs/ext2.c | 38 ++++++++- kernel/fs/ext2.h | 8 +- kernel/fs/vfs.c | 180 ++++++++++++++++++++++++++++++++++++++++- kernel/fs/vfs.h | 51 ++++++++++-- kernel/kernel.c | 51 ++++++++---- kernel/kernel.h | 9 ++- menu.lst | 4 +- rmmod/rmmod.asm | 43 +++++++++- 15 files changed, 409 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 3814c25..74375cd 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,9 @@ FLOPPY=/dev/fd0 FLOPPY_MOUNT=./mnt_flp FLOPPY_IMAGE=hos.flp GRUB_IMAGE=grub.flp +INITRD=hos_initrd +INITRD_MOUNT=./mnt_initrd +INITRD_SIZE=100 #initrd size in kb # Do not print "Entering directory ..." MAKEFLAGS += --no-print-directory @@ -17,7 +20,7 @@ all: clean: -make -C kernel clean -make -C rmmod clean - -rm -f *~ *.out hos.flp \#* + -rm -f *~ *.out hos.flp \#* hos_initrd hos_initrd.gz parallel.out grub: @@ -32,21 +35,34 @@ grub_image: dd if=$(FLOPPY) of=$(GRUB_IMAGE) install: + gzip -c $(INITRD) > $(INITRD).gz -mkdir $(FLOPPY_MOUNT) mount -t ext2 $(FLOPPY) $(FLOPPY_MOUNT) cp kernel/kernel.bin $(FLOPPY_MOUNT) cp rmmod/rmmod.bin $(FLOPPY_MOUNT) cp menu.lst $(FLOPPY_MOUNT)/boot/grub + cp $(INITRD).gz $(FLOPPY_MOUNT)/$(INITRD).gz umount $(FLOPPY_MOUNT) -rmdir $(FLOPPY_MOUNT) install_img: + gzip -c $(INITRD) > $(INITRD).gz -mkdir $(FLOPPY_MOUNT) cp $(GRUB_IMAGE) $(FLOPPY_IMAGE) mount -t ext2 -o loop $(FLOPPY_IMAGE) $(FLOPPY_MOUNT) cp kernel/kernel.bin $(FLOPPY_MOUNT) cp rmmod/rmmod.bin $(FLOPPY_MOUNT) cp menu.lst $(FLOPPY_MOUNT)/boot/grub + cp $(INITRD).gz $(FLOPPY_MOUNT)/$(INITRD).gz umount $(FLOPPY_MOUNT) -rmdir $(FLOPPY_MOUNT) +initrd: + dd if=/dev/zero of=$(INITRD) bs=1024 count=$(INITRD_SIZE) + mke2fs -Fv -m0 $(INITRD) + -mkdir $(INITRD_MOUNT) +# mount -t ext2 -o loop $(INITRD) $(INITRD_MOUNT) +# mkdir $(INITRD_MOUNT)/bin +# umount $(INITRD_MOUNT) + rm -rf $(INITRD_MOUNT) + diff --git a/kernel/Makefile b/kernel/Makefile index 6bb31d6..644dde6 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -19,7 +19,7 @@ all: Asm_Kernel C_Kernel $(LD) $(LD_FLAGS) -Map kernel.map \ boot.o kernel.o asmfuncs.o mm.o vmm.o parallel.o conv.o kout.o \ vconsole.o display.o devices.o pic.o keyboard.o ramdisk.o vfs.o \ - devfs.o -o kernel.bin + devfs.o ext2.o -o kernel.bin Asm_Kernel: $(NASM) $(NASM_FLAGS) -l boot.lst boot.asm -o boot.o @@ -40,6 +40,7 @@ C_Kernel: $(CC) $(CC_FLAGS) -c block/ramdisk.c -o ramdisk.o $(CC) $(CC_FLAGS) -c fs/devfs.c -o devfs.o $(CC) $(CC_FLAGS) -c fs/vfs.c -o vfs.o + $(CC) $(CC_FLAGS) -c fs/ext2.c -o ext2.o ################################################# # Clean up the source directory of any binaries # diff --git a/kernel/block/ramdisk.c b/kernel/block/ramdisk.c index 41db716..0ead280 100644 --- a/kernel/block/ramdisk.c +++ b/kernel/block/ramdisk.c @@ -13,36 +13,36 @@ ramdisk_t *ramdisks[256]; int ramdisk_init(major_t major) { - dev_driver_t *ramdisk_driver; - if (( ramdisk_driver = New(dev_driver_t) )) - { - ramdisk_driver->block_read = ramdisk_block_read; - ramdisk_driver->block_write = ramdisk_block_write; - devices_register_major('b', major, ramdisk_driver); - return 0; - } - return -1; + dev_driver_t *ramdisk_driver; + if (( ramdisk_driver = New(dev_driver_t) )) + { + ramdisk_driver->block_read = ramdisk_block_read; + ramdisk_driver->block_write = ramdisk_block_write; + devices_register_major('b', major, ramdisk_driver); + return 0; + } + return -1; } minor_t ramdisk_new(u32_t size) { - int i; - for (i = 0; i < 256; i++) - { - if (!ramdisks[i]) + int i; + for (i = 0; i < 256; i++) { - void *start; - if (( start = kmalloc(size) )) - { - ramdisks[i] = New(ramdisk_t); - ramdisks[i]->start = start; - ramdisks[i]->size = size; - return i; - } - return -2; + if (!ramdisks[i]) + { + void *start; + if (( start = kmalloc(size) )) + { + ramdisks[i] = New(ramdisk_t); + ramdisks[i]->start = start; + ramdisks[i]->size = size; + return i; + } + return -2; + } } - } - return -1; + return -1; } minor_t ramdisk_register(void *ramdisk, u32_t size) @@ -64,12 +64,12 @@ minor_t ramdisk_register(void *ramdisk, u32_t size) int ramdisk_remove(minor_t minor) { if (ramdisks[minor]) - { - kfree(ramdisks[minor]->start); - kfree(ramdisks[minor]); - ramdisks[minor] = NULL; - return 0; - } + { + kfree(ramdisks[minor]->start); + kfree(ramdisks[minor]); + ramdisks[minor] = NULL; + return 0; + } return -1; } diff --git a/kernel/fs/devfs.c b/kernel/fs/devfs.c index 9a27e96..07b4922 100644 --- a/kernel/fs/devfs.c +++ b/kernel/fs/devfs.c @@ -7,10 +7,17 @@ #include "fs/devfs.h" #include "fs/devices.h" #include "fs/vfs.h" +#include "block/ramdisk.h" -void devfs_init(minor_t rd_minor) +int devfs_init() { -// vfs_mount(MAJORB_RAMDISK, rd_minor, FS_EXT2, "/dev"); + minor_t devfs_minor = ramdisk_new(DEVFS_SIZE); + if (devfs_minor < 0) + return -1; +// ext2_mkfs(MAJORB_RAMDISK, devfs_minor); +// vfs_mount(MAJORB_RAMDISK, rd_minor, FS_EXT2, "/dev"); +// mknod(MAJORB_RAMDISK, initrd_minor, 0600, "/dev/rd0"); + return 0; } diff --git a/kernel/fs/devfs.h b/kernel/fs/devfs.h index f006b34..b1f4b33 100644 --- a/kernel/fs/devfs.h +++ b/kernel/fs/devfs.h @@ -9,7 +9,9 @@ #include "hos_defines.h" #include "fs/devices.h" -void devfs_init(minor_t rd_minor); +#define DEVFS_SIZE 102400 + +int devfs_init(); #endif diff --git a/kernel/fs/devices.c b/kernel/fs/devices.c index a73f115..2a97f62 100644 --- a/kernel/fs/devices.c +++ b/kernel/fs/devices.c @@ -8,6 +8,7 @@ #include "kernel.h" #include "char/parallel.h" #include "char/vconsole.h" +#include "block/ramdisk.h" dev_driver_t *drivers[2][256]; @@ -17,7 +18,7 @@ void devices_init() { parallel_init(MAJORC_PARALLEL); vconsole_init(MAJORC_VCONSOLE); - // ramdisk_init(MAJORB_RAMDISK); + ramdisk_init(MAJORB_RAMDISK); } diff --git a/kernel/fs/devices.h b/kernel/fs/devices.h index 17b83d0..6020d97 100644 --- a/kernel/fs/devices.h +++ b/kernel/fs/devices.h @@ -19,6 +19,7 @@ typedef short major_t; typedef short minor_t; +typedef unsigned int device_t; typedef struct { int (*block_read)(minor_t minor, u32_t blockStart, u32_t blocks, void *buffer); diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index 917c586..eb919ff 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -6,11 +6,41 @@ #include "hos_defines.h" #include "fs/devices.h" #include "kout.h" +#include "ext2.h" +#include "mm/vmm.h" +#include "fs/vfs.h" -void ext2_read_super(major_t major, minor_t minor); + +int ext2_init(int fsID) { - ext2_super_block_t *super = kmalloc(1024); - block_read(major, minor, 2, 2, super); - kprintf("Magic: 0x%x\n", super->s_magic); + vfs_fs_t *fs; + if (( fs = New(vfs_fs_t) )) + { + fs->mount_super = ext2_mount_super; + fs->mkfs = ext2_mkfs; + vfs_register_fs(fsID, fs); + return 0; + } + return -1; +} + + +int ext2_mkfs(major_t major, minor_t minor) +{ + return 0; +} + + +// read the superblock of the filesystem and return a pointer to it +void *ext2_mount_super(major_t major, minor_t minor) +{ + ext2_super_block_t *super = kmalloc(1024); + block_read(major, minor, 2, 2, super); + if (super->s_magic != EXT2_MAGIC) + { + kfree(super); + return NULL; + } + return super; } diff --git a/kernel/fs/ext2.h b/kernel/fs/ext2.h index fc5ed84..2fae121 100644 --- a/kernel/fs/ext2.h +++ b/kernel/fs/ext2.h @@ -9,6 +9,8 @@ #include "hos_defines.h" #include "fs/devices.h" +#define EXT2_MAGIC 0xEF53 + typedef struct { u32_t s_inodes_count; /* Inodes count */ u32_t s_blocks_count; /* Blocks count */ @@ -53,7 +55,7 @@ typedef struct { /* * Performance hints... */ - u8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ + u8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate */ u8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ u16_t s_padding1; @@ -75,7 +77,9 @@ typedef struct { } ext2_super_block_t; -void ext2_read_super(major_t major, minor_t minor); +int ext2_init(int fsID); +void *ext2_mount_super(major_t major, minor_t minor); +int ext2_mkfs(major_t major, minor_t minor); #endif diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index d16b376..ddc0fe9 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -1,10 +1,186 @@ // vfs.c // Author: Josh Holtrop // Date: 08/22/04 -// Modified: 08/22/04 +// Modified: 12/20/04 #include "hos_defines.h" +#include "kout.h" #include "fs/vfs.h" +#include "fs/ext2.h" +#include "kernel.h" +#include "mm/vmm.h" -vfs_mount_t *firstMount; +vfs_fs_t *fses[VFS_MAX_FS]; +vfs_node_t *vfsMountTree; + +int vfs_init() +{ + k_check(ext2_init(FS_EXT2), "ext2_init() failed!"); + return 0; +} + +int vfs_register_fs(int fsn, vfs_fs_t *fs) +{ + if (fsn < 0 || fsn >= VFS_MAX_FS || fses[fsn]) + { + kprintf("Invalid filesystem register: %d\n", fsn); + return -1; + } + fses[fsn] = fs; + return 0; +} + +int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint) +{ + if (mountPoint[0] != '/') + return -1; // mount point must be absolute + if (fsType < 0 || fsType >= VFS_MAX_FS || !fses[fsType]) + return -2; // invalid filesystem type + if (vfs_find_mount(mountPoint)) + { + return -5; // mount point already mounted + } + void *super = fses[fsType]->mount_super(maj, min); + if (!super) + return -6; // filesystem superblock not correctly identified + vfs_mount_t *mnt = New(vfs_mount_t); + if (!mnt) + return -3; // could not allocate memory + mnt->refs = 0; + mnt->major = maj; + mnt->minor = min; + mnt->super = super; + if (vfs_add_mount(mnt, mountPoint)) + { + kfree(mnt); + return -4; // could not add mount + } + return 0; +} + +int vfs_add_mount(vfs_mount_t *mnt, char *mountPoint) +{ + vfs_node_t *node = vfsMountTree; + char *mp = mountPoint; + if (!vfsMountTree) + { + vfsMountTree = New(vfs_node_t); + node = vfsMountTree; + node->chr = *mp; + node->up = NULL; + node->next = NULL; + node->down = NULL; + node->mount = NULL; + } + for (;;) + { + if (node->chr == *mp) // got a match + { + mp++; + if (*mp == 0) + { + if (node->mount) + return -1; // mount point already taken + node->mount = mnt; + return 0; + } + if (node->down) + node = node->down; + else + { + node->down = New(vfs_node_t); + node->down->up = node; + node = node->down; + node->next = NULL; + node->down = NULL; + node->mount = NULL; + node->chr = *mp; + } + } + else if (node->next) + { + node = node->next; + } + else // add a node for this character + { + node->next = New(vfs_node_t); + node->next->up = node->up; + node = node->next; + node->next = NULL; + node->down = NULL; + node->mount = NULL; + node->chr = *mp; + } + } +} + +vfs_mount_match_t vfs_get_rel_path(char *path) +{ + vfs_mount_match_t matched; + char *pp = path; + int length = 0; + vfs_node_t *node = vfsMountTree; + while (*pp) + { + if (!node) + break; + if (node->chr == *pp) // got a character match + { + if (node->mount) // and there is something mounted here + { + matched.major = node->mount->major; + matched.minor = node->mount->minor; + matched.length = length; + } + pp++; + length++; + node = node->down; + } + else + node = node->next; + } + return matched; +} + +vfs_mount_t *vfs_find_mount(char *mountPoint) +{ + char *mp = mountPoint; + vfs_node_t *node = vfsMountTree; + while (node) + { + if (node->chr == *mp) + { + mp++; + if (*mp == 0) // we matched the whole mount point string + return node->mount; + node = node->down; + } + else + node = node->next; + } + return NULL; +} + +/*void vfs_dump_tree() +{ + vfs_dump_node(vfsMountTree, 0); +} + +void vfs_dump_node(vfs_node_t *node, int level) +{ + int i; + for (i = 0; i < level; i++) + { + putc(' '); + } + kprintf("%c (0x%x) mount: 0x%x, up: 0x%x, next:0x%x, down:0x%x\n", node->chr, node, node->mount, node->up, node->next, node->down); + node = node->down; + if (!node) + return; + while (node) + { + vfs_dump_node(node, level + 1); + node = node->next; + } +}*/ diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index 8432023..6e2c035 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -1,7 +1,7 @@ // vfs.h // Author: Josh Holtrop // Date: 08/22/04 -// Modified: 08/22/04 +// Modified: 12/20/04 #ifndef __HOS_VFS_H__ #define __HOS_VFS_H__ __HOS_VFS_H__ @@ -10,14 +10,51 @@ #include "fs/devices.h" #define FS_EXT2 1 +#define VFS_MAX_FS 10 -typedef struct { - char *name; - void *super; - void *next; - major_t major; - minor_t minor; + +typedef struct +{ + int refs; + void *super; + major_t major; + minor_t minor; } vfs_mount_t; +typedef struct +{ + void *(*mount_super)(major_t major, minor_t minor); + int (*mkfs)(major_t major, minor_t minor); +} vfs_fs_t; + +struct vfs_node_s +{ + char chr; + vfs_mount_t *mount; + struct vfs_node_s *up; + struct vfs_node_s *next; + struct vfs_node_s *down; +}; + +typedef struct vfs_node_s vfs_node_t; + +typedef struct +{ + major_t major; + minor_t minor; + int length; +} vfs_mount_match_t; + + +int vfs_init(); +int vfs_mount(major_t maj, minor_t min, int fsType, char *mountPoint); +int vfs_register_fs(int fsn, vfs_fs_t *fs); +int vfs_add_mount(vfs_mount_t *mnt, char *mountPoint); +vfs_mount_t *vfs_find_mount(char *mountPoint); +vfs_mount_match_t vfs_get_rel_path(char *path); +/*void vfs_dump_tree(); +void vfs_dump_node(vfs_node_t *node, int level);*/ + + #endif diff --git a/kernel/kernel.c b/kernel/kernel.c index 324f3ec..44447ea 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -35,8 +35,6 @@ real_mode_param_t rm_params; char mb_cmdline[256]; int criticalCounter; // semaphore for if interrupts are disabled u32_t timer; // number of IRQ 0's -minor_t devfs_minor = -1; -minor_t initrd_minor = -1; extern u32_t mm_freepages; @@ -99,6 +97,7 @@ mb_module_t *k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic) return real_mode_module; } + /* Main kernel initialization routine */ void k_init() { @@ -112,21 +111,32 @@ void k_init() devices_init(); if (real_mode_module) { - if (rm_params.vid_mem) // there is video memory to map in - vmm_mapn(0xF0000000, (u32_t)rm_params.vid_addr, (rm_params.vid_mem >> 12) + 1); -// initrd_minor = ramdisk_register(initrd, 2880*512); + if (rm_params.vid_mem) // there is video memory to map in + vmm_mapn(0xF0000000, (u32_t)rm_params.vid_addr, (rm_params.vid_mem >> 12) + 1); } - display_init(); //get us some virtual consoles to look at + display_init(); //get us some virtual consoles to look at display_activate(11); kprintf("HOS v0.16 initializing...\n"); kprintf("Kernel load size: %d (0x%x) bytes (%d kb)\n", kernel_size(), kernel_size(), kernel_size() >> 10); kprintf("Kernel memory size: %d (0x%x) bytes (%d kb)\n", kernel_size_used(), kernel_size_used(), kernel_size_used() >> 10); - if ((devfs_minor = ramdisk_new(4096)) < 0) - { - kprintf("\e31;1mk_init(): Could not obtain minor mumber for devfs ram disk!\n"); - halt(); - } - devfs_init(devfs_minor); + + k_check(vfs_init(), "vfs_init() failed!"); + k_check(devfs_init(), "devfs_init() failed!"); + + int i; + for (i = 0; i < mb_info_block.mods_count; i++) + { + kprintf("Loaded kernel module %d: 0x%x - 0x%x (%d bytes)\n", i, mb_modules[i].mod_start, mb_modules[i].mod_end, mb_modules[i].mod_end - mb_modules[i].mod_start); + if (((mb_modules[i].mod_end - mb_modules[i].mod_start) > 0x43A) && + (*(u16_t *)(mb_modules[i].mod_start + 0x438) == EXT2_MAGIC)) + { + // we found an initrd + minor_t initrd_minor = ramdisk_register((void *)mb_modules[i].mod_start, mb_modules[i].mod_end - mb_modules[i].mod_start); + kprintf("initrd (%dkb) loaded\n", (mb_modules[i].mod_end - mb_modules[i].mod_start) >> 10); + k_check(vfs_mount(MAJORB_RAMDISK, initrd_minor, FS_EXT2, "/"), "Could not mount initrd to /!"); + } + } + criticalCounter--; } @@ -135,12 +145,12 @@ void isr(u32_t num) criticalCounter++; switch (num) { - case 0x20: // timer + case 0x20: // timer (*(u16_t *)CONSOLE_MEMORY)++; timer++; pic_eoi(); break; - case 0x21: // keyboard + case 0x21: // keyboard isr_keyboard(); pic_eoi(); break; @@ -152,16 +162,25 @@ void isr(u32_t num) } -void k_enter_critical() // functions for implementing "atomic actions" +void k_enter_critical() // functions for implementing "atomic actions" { disable_ints(); criticalCounter++; } -void k_leave_critical() +void k_leave_critical() { criticalCounter--; if (!criticalCounter) enable_ints(); } +void k_check(int val, char *msg) +{ + if (val) + { + kprintf("\e[31;1m%s\n", msg); + halt(); + } +} + diff --git a/kernel/kernel.h b/kernel/kernel.h index cfbc419..db234e7 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -19,10 +19,11 @@ typedef struct { /* returns true to callee if we should jump to a real mode module */ mb_module_t *k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic); -void k_init(); -void isr(); -void k_enter_critical(); // functions for implementing "atomic actions" -void k_leave_critical(); +void _init(); +void isr(); +void k_enter_critical(); // functions for implementing "atomic actions" +void k_leave_critical(); +void k_check(int val, char *msg); #endif diff --git a/menu.lst b/menu.lst index bc56c19..04fa1f0 100644 --- a/menu.lst +++ b/menu.lst @@ -5,5 +5,5 @@ default 0 title HOS 0.16 root (fd0) kernel /kernel.bin -#module /rmmod.bin - +module /rmmod.bin +module /hos_initrd.gz diff --git a/rmmod/rmmod.asm b/rmmod/rmmod.asm index 372d441..8bf587e 100644 --- a/rmmod/rmmod.asm +++ b/rmmod/rmmod.asm @@ -3,6 +3,8 @@ ; Author: Josh Holtrop ; Date: 09/20/04 +%define VIRT_OFFSET 0xC0000000 + ; the bootstrap process will jump us to 0x0:0x5010 so we'd better be ready for it [org 0x5000] [bits 16] @@ -25,16 +27,22 @@ start_refreshed: mov [dat_rmadd], ecx mov [dat_retn], ebx +; begin real-mode code initialization, etc... + +; get ready to go back to pmode and return to kernel initialization mov ebx, [dat_retn] - lgdt [gdtrbs32] + lgdt [gdtrlin32] mov eax, cr0 or eax, 0x01 mov cr0, eax - jmp KERNEL_CODE_BS32:segmented_start + jmp KERNEL_CODE_LIN32:segmented_start [bits 32] segmented_start: + lgdt [gdtrbs32] + jmp KERNEL_CODE_BS32:offset_continue+VIRT_OFFSET +offset_continue: mov cx, KERNEL_DATA_BS32 mov ss, cx mov ds, cx @@ -83,6 +91,37 @@ putString_loop_done: pop bp ret +;------------------------------------------------------- +gdtrlin32: + dw gdt_endlin32-gdtlin32-1 + dd gdtlin32 +gdtlin32: ;null descriptor + dd 0 + dd 0 + +KERNEL_CODE_LIN32 equ $-gdtlin32 + db 0xff ;limit 7:0 + db 0xff ;limit 15:8 + db 0x00 ;base 7:0 + db 0x00 ;base 15:8 + db 0x00 ;base 23:16 + db 0x9a ;access + db 0xcf ;flags / limit 19:16 + db 0x00 ;base 31:24 + +KERNEL_DATA_LIN32 equ $-gdtlin32 + db 0xff ;limit 7:0 + db 0xff ;limit 15:8 + db 0x00 ;base 7:0 + db 0x00 ;base 15:8 + db 0x00 ;base 23:16 + db 0x92 ;access + db 0xcf ;flags / limit 19:16 + db 0x00 ;base 31:24 + +gdt_endlin32: + + ;------------------------------------------------------- gdtrbs32: dw gdt_endbs32-gdtbs32-1