KraKern

C++ Kernel
Log | Files | Refs | README | LICENSE | git clone https://git.ne02ptzero.me/git/KraKern

commit 45989ac0b1b0ed44e53091e7388086eba83d1487
parent d83388597073fdeb6be07f8d0ef1911aef6ef3a0
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Sat,  6 Feb 2016 15:27:06 +0100

Add(Disk): Add IDE & ext2 support:

ext2 not fully functionnal yet

Diffstat:
Aincludes/core/IDE.hpp | 21+++++++++++++++++++++
Mincludes/core/Kernel.hpp | 2++
Akernel/IDE.cpp | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mkernel/Kernel.cpp | 1+
Mkernel/Makefile | 2+-
Mmodules/x86/Makefile | 2+-
Amodules/x86/ModuleExt2.cpp | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/x86/ModuleExt2.hpp | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmodules/x86/modules_conf.cpp | 4+++-
Mqemu.sh | 2+-
10 files changed, 373 insertions(+), 4 deletions(-)

diff --git a/includes/core/IDE.hpp b/includes/core/IDE.hpp @@ -0,0 +1,21 @@ +#ifndef __IDE__ +# define __IDE__ + +# include <os.h> + +class IDE { + public: + IDE(void); + ~IDE(void); + + int read(int drive, int offset, char *buf, int count); + + private: + int _bl_write(int drive, int numblock, int count, char *buf); + int _bl_read(int drive, int numblock, int count, char *buf); + int _bl_common(int drive, int numblock, int count); +}; + +# include <Kernel.hpp> + +#endif diff --git a/includes/core/Kernel.hpp b/includes/core/Kernel.hpp @@ -8,6 +8,7 @@ # include <Memory.hpp> # include <FileSystem.hpp> # include <ProcessTable.hpp> +# include <IDE.hpp> class Modules; @@ -26,6 +27,7 @@ class Kernel { FileSystem fs; ProcessTable pt; Modules *mods; + IDE ide; }; # include <Modules.hpp> diff --git a/kernel/IDE.cpp b/kernel/IDE.cpp @@ -0,0 +1,60 @@ +# include <IDE.hpp> + +IDE::IDE(void) { + return ; +} + +IDE::~IDE(void) { + return ; +} + +int IDE::read(int drive, int offset, char *buf, int count) { + char *bl_buf; + int beg, end, blocks; + + beg = offset / 512; + end = (offset + count) / 512; + blocks = end - beg + 1; + bl_buf = (char *)__kern.mem.kmalloc(blocks * 512); + this->_bl_read(drive, beg, blocks, bl_buf); + memcpy(buf, (char *)(bl_buf + offset % 512), count); + __kern.mem.kfree(bl_buf); + return count; +} + +int IDE::_bl_common(int drive, int numblock, int count) { + __kern.io.obyte(0x1F1, 0x00); + __kern.io.obyte(0x1F2, count); + __kern.io.obyte(0x1F3, numblock); + __kern.io.obyte(0xF14, numblock >> 8); + __kern.io.obyte(0xF15, numblock >> 16); + __kern.io.obyte(0x1F6, 0xE0 | (drive << 4) | ((numblock >> 24) & 0x0F)); + return 0; +} + +int IDE::_bl_read(int drive, int numblock, int count, char *buf) { + u16 tmp; + + this->_bl_common(drive, numblock, count); + __kern.io.obyte(0x1F7, 0x20); + while (!(__kern.io.ibyte(0x1F7) & 0x08)); + for (int idx = 0; idx < 256 * count; idx++) { + tmp = __kern.io.iword(0x1F0); + buf[idx * 2] = tmp; + buf[idx * 2 + 1] = tmp >> 8; + } + return count; +} + +int IDE::_bl_write(int drive, int numblock, int count, char *buf) { + u16 tmp; + + this->_bl_common(drive, numblock, count); + __kern.io.obyte(0x1F7, 0x30); + while (!(__kern.io.ibyte(0x1F7) & 0x08)); + for (int idx = 0; idx < 256 * count; idx++) { + tmp = (buf[idx * 2 + 1] << 8) | buf[idx * 2]; + __kern.io.oword(0xF10, tmp); + } + return count; +} diff --git a/kernel/Kernel.cpp b/kernel/Kernel.cpp @@ -40,6 +40,7 @@ void Kernel::init(multiboot_info *mbi) { this->pt.init(); this->mods = &__modules; this->mods->init(); + this->ide = *(new IDE()); this->ready(); while (1); } diff --git a/kernel/Makefile b/kernel/Makefile @@ -1 +1 @@ -OBJS += kernel/main.o kernel/Io.o kernel/Kernel.o kernel/Memory.o kernel/Process.o kernel/File.o kernel/FileSystem.o kernel/ProcessTable.o kernel/Modules.o +OBJS += kernel/main.o kernel/Io.o kernel/Kernel.o kernel/Memory.o kernel/Process.o kernel/File.o kernel/FileSystem.o kernel/ProcessTable.o kernel/Modules.o kernel/IDE.o diff --git a/modules/x86/Makefile b/modules/x86/Makefile @@ -1 +1 @@ -OBJS += modules/$(ARCH)/modules_conf.o modules/$(ARCH)/ModuleKeyboard.o modules/$(ARCH)/ModuleTime.o +OBJS += modules/$(ARCH)/modules_conf.o modules/$(ARCH)/ModuleKeyboard.o modules/$(ARCH)/ModuleTime.o modules/$(ARCH)/ModuleExt2.o diff --git a/modules/x86/ModuleExt2.cpp b/modules/x86/ModuleExt2.cpp @@ -0,0 +1,130 @@ +# include <ModuleExt2.hpp> + +ModuleExt2::ModuleExt2(char *name, u8 t) : Module(name, t) { + ; +} + +ModuleExt2::~ModuleExt2(void) { + +} + +struct disk *ModuleExt2::_get_disk_info(int n) { + struct disk *hd; + int i, j; + + hd = (struct disk *)__kern.mem.kmalloc(sizeof(struct disk)); + if (!hd) + __kern.io.panic("ext2: _get_disk_info(): Cannot allocate disk structure"); + hd->device = n; + hd->sb = this->_read_sb(n); + hd->blocksize = 1024 << hd->sb->s_log_block_size; + i = (hd->sb->s_blocks_count / hd->sb->s_blocks_per_group) + + ((hd->sb->s_blocks_count % hd->sb->s_blocks_per_group) ? 1 : 0); + j = (hd->sb->s_inodes_count / hd->sb->s_inodes_per_group) + + ((hd->sb->s_inodes_count % hd->sb->s_inodes_per_group) ? 1 : 0); + hd->groups = (i > j) ? i : j; + hd->gd = this->_read_gd(hd); + return hd; +} + +struct ext2_super_block *ModuleExt2::_read_sb(int n) { + struct ext2_super_block *sb; + + sb = (struct ext2_super_block *)__kern.mem.kmalloc(sizeof(struct ext2_super_block)); + if (!sb) + __kern.io.panic("ext2: _read_sb(): Cannot allocate memory"); + __kern.ide.read(n, 1024, (char *)sb, sizeof(struct ext2_super_block)); + return sb; +} + +struct ext2_group_desc *ModuleExt2::_read_gd(struct disk *d) { + struct ext2_group_desc *gd; + int offset, gd_size; + + offset = (d->blocksize == 1024) ? 2048 : d->blocksize; + gd_size = d->groups * sizeof(struct ext2_group_desc); + gd = (struct ext2_group_desc *)__kern.mem.kmalloc(gd_size); + if (!gd) + __kern.io.panic("ext2: _read_gd(): Cannot allocate memory"); + __kern.ide.read(d->device, offset, (char *)gd, gd_size); + return gd; +} + +struct ext2_inode *ModuleExt2::_read_inode(struct disk *d, int i_num) { + struct ext2_inode *inode; + int gr_num, index, offset; + + inode = (struct ext2_inode *)__kern.mem.kmalloc(sizeof(struct ext2_inode)); + if (!inode) + __kern.io.panic("ext2: _read_inode(): Cannot allocate memory"); + gr_num = (i_num - 1) / d->sb->s_inodes_per_group; + index = (i_num - 1) & d->sb->s_inodes_per_group; + offset = d->gd[gr_num].bg_inode_table * d->blocksize + index * d->sb->s_inode_size; + __kern.ide.read(d->device, offset, (char *)inode, d->sb->s_inode_size); + return inode; +} + +char *ModuleExt2::_read_file(struct disk *hd, struct ext2_inode *inode) { + char *mmap_base, *mmap_head, *buf; + int *p, *pp, *ppp, n, size; + + buf = (char *)__kern.mem.kmalloc(hd->blocksize); + p = (int *)__kern.mem.kmalloc(hd->blocksize); + pp = (int *)__kern.mem.kmalloc(hd->blocksize); + ppp = (int *)__kern.mem.kmalloc(hd->blocksize); + if (!buf || !p || !pp || !ppp) + __kern.io.panic("ext2: _read_file(): Cannot allocate memory"); + size = inode->i_size; + mmap_head = mmap_base = (char *)__kern.mem.kmalloc(size); + for (int i = 0; i < 12 && inode->i_block[i]; i++) { + __kern.ide.read(hd->device, inode->i_block[i] * hd->blocksize, buf, hd->blocksize); + n = ((size > (int)hd->blocksize) ? hd->blocksize : size); + memcpy(mmap_head, buf, n); + mmap_head += n; + size -= n; + } + if (inode->i_block[12]) { + __kern.ide.read(hd->device, inode->i_block[12] * hd->blocksize, (char *)p, hd->blocksize); + for (int i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) { + __kern.ide.read(hd->device, p[i] * hd->blocksize, buf, hd->blocksize); + n = ((size > (int)hd->blocksize) ? hd->blocksize : size); + memcpy(mmap_head, buf, n); + mmap_head += n; + size -= n; + } + } + if (inode->i_block[13]) { + __kern.ide.read(hd->device, inode->i_block[12] * hd->blocksize, (char *)p, hd->blocksize); + for (int i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) { + __kern.ide.read(hd->device, p[i] * hd->blocksize, (char *)pp, hd->blocksize); + for (int j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) { + __kern.ide.read(hd->device, pp[j] * hd->blocksize, buf, hd->blocksize); + n = ((size > (int)hd->blocksize) ? hd->blocksize : size); + memcpy(mmap_head, buf, n); + mmap_head += n; + size -= n; + } + } + } + if (inode->i_block[14]) { + __kern.ide.read(hd->device, inode->i_block[14] * hd->blocksize, (char *)p, hd->blocksize); + for (int i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) { + __kern.ide.read(hd->device, p[i] * hd->blocksize, (char *)pp, hd->blocksize); + for (int j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) { + __kern.ide.read(hd->device, pp[j] * hd->blocksize, (char *)ppp, hd->blocksize); + for (int k = 0; k < (int)hd->blocksize / 4 && ppp[k]; k++) { + __kern.ide.read(hd->device, ppp[k] * hd->blocksize, buf, hd->blocksize); + n = ((size > (int)hd->blocksize) ? hd->blocksize : size); + memcpy(mmap_head, buf, n); + mmap_head += n; + size -= n; + } + } + } + } + __kern.mem.kfree(buf); + __kern.mem.kfree(p); + __kern.mem.kfree(pp); + __kern.mem.kfree(ppp); + return mmap_base; +} diff --git a/modules/x86/ModuleExt2.hpp b/modules/x86/ModuleExt2.hpp @@ -0,0 +1,153 @@ +#ifndef __MODULE_EXT2__ +# define __MODULE_EXT2__ +# define __DO_NOT_LOAD_MODULES__ +# include <Module.hpp> + +struct ext2_super_block; +struct ext2_group_desc; +struct ext2_inode; +struct disk; + +class ModuleExt2 : public Module { + public: + ModuleExt2(char *name, u8 t); + ~ModuleExt2(void); + + protected: + struct disk *_get_disk_info(int n); + struct ext2_super_block *_read_sb(int n); + struct ext2_group_desc *_read_gd(struct disk *d); + struct ext2_inode *_read_inode(struct disk *d, int i_num); + char *_read_file(struct disk *d, struct ext2_inode *i); +}; + +// List of ext2 structures. + +struct ext2_super_block { + u32 s_inodes_count; /* Total number of inodes */ + u32 s_blocks_count; /* Total number of blocks */ + u32 s_r_blocks_count; /* Total number of blocks reserved for the super user */ + u32 s_free_blocks_count; /* Total number of free blocks */ + u32 s_free_inodes_count; /* Total number of free inodes */ + u32 s_first_data_block; /* Id of the block containing the superblock structure */ + u32 s_log_block_size; /* Used to compute block size = 1024 << s_log_block_size */ + u32 s_log_frag_size; /* Used to compute fragment size */ + u32 s_blocks_per_group; /* Total number of blocks per group */ + u32 s_frags_per_group; /* Total number of fragments per group */ + u32 s_inodes_per_group; /* Total number of inodes per group */ + u32 s_mtime; /* Last time the file system was mounted */ + u32 s_wtime; /* Last write access to the file system */ + u16 s_mnt_count; /* How many `mount' since the last was full verification */ + u16 s_max_mnt_count; /* Max count between mount */ + u16 s_magic; /* = 0xEF53 */ + u16 s_state; /* File system state */ + u16 s_errors; /* Behaviour when detecting errors */ + u16 s_minor_rev_level; /* Minor revision level */ + u32 s_lastcheck; /* Last check */ + u32 s_checkinterval; /* Max. time between checks */ + u32 s_creator_os; /* = 5 */ + u32 s_rev_level; /* = 1, Revision level */ + u16 s_def_resuid; /* Default uid for reserved blocks */ + u16 s_def_resgid; /* Default gid for reserved blocks */ + u32 s_first_ino; /* First inode useable for standard files */ + u16 s_inode_size; /* Inode size */ + u16 s_block_group_nr; /* Block group hosting this superblock structure */ + u32 s_feature_compat; + u32 s_feature_incompat; + u32 s_feature_ro_compat; + u8 s_uuid[16]; /* Volume id */ + char s_volume_name[16]; /* Volume name */ + char s_last_mounted[64]; /* Path where the file system was last mounted */ + u32 s_algo_bitmap; /* For compression */ + u8 s_padding[820]; +} __attribute__ ((packed)); + +struct disk { + int device; + struct ext2_super_block *sb; + u32 blocksize; + u16 groups; /* Total number of groups */ + struct ext2_group_desc *gd; +}; + +struct ext2_group_desc { + u32 bg_block_bitmap; /* Id of the first block of the "block bitmap" */ + u32 bg_inode_bitmap; /* Id of the first block of the "inode bitmap" */ + u32 bg_inode_table; /* Id of the first block of the "inode table" */ + u16 bg_free_blocks_count; /* Total number of free blocks */ + u16 bg_free_inodes_count; /* Total number of free inodes */ + u16 bg_used_dirs_count; /* Number of inodes allocated to directories */ + u16 bg_pad; /* Padding the structure on a 32bit boundary */ + u32 bg_reserved[3]; /* Future implementation */ +} __attribute__ ((packed)); + +struct ext2_inode { + u16 i_mode; /* File type + access rights */ + u16 i_uid; + u32 i_size; + u32 i_atime; + u32 i_ctime; + u32 i_mtime; + u32 i_dtime; + u16 i_gid; + u16 i_links_count; + u32 i_blocks; /* 512 bytes blocks ! */ + u32 i_flags; + u32 i_osd1; + + /* + * [0] -> [11] : block number (32 bits per block) + * [12] : indirect block number + * [13] : bi-indirect block number + * [14] : tri-indirect block number + */ + u32 i_block[15]; + u32 i_generation; + u32 i_file_acl; + u32 i_dir_acl; + u32 i_faddr; + u8 i_osd2[12]; +} __attribute__ ((packed)); + +struct directory_entry { + u32 inode; /* inode number or 0 (unused) */ + u16 rec_len; /* offset to the next dir. entry */ + u8 name_len; /* name length */ + u8 file_type; + char name; +} __attribute__ ((packed)); + + +/* super_block: s_errors */ +# define EXT2_ERRORS_CONTINUE 1 +# define EXT2_ERRORS_RO 2 +# define EXT2_ERRORS_PANIC 3 +# define EXT2_ERRORS_DEFAULT 1 + +/* inode: i_mode */ +# define EXT2_S_IFMT 0xF000 /* format mask */ +# define EXT2_S_IFSOCK 0xC000 /* socket */ +# define EXT2_S_IFLNK 0xA000 /* symbolic link */ +# define EXT2_S_IFREG 0x8000 /* regular file */ +# define EXT2_S_IFBLK 0x6000 /* block device */ +# define EXT2_S_IFDIR 0x4000 /* directory */ +# define EXT2_S_IFCHR 0x2000 /* character device */ +# define EXT2_S_IFIFO 0x1000 /* fifo */ + +# define EXT2_S_ISUID 0x0800 /* SUID */ +# define EXT2_S_ISGID 0x0400 /* SGID */ +# define EXT2_S_ISVTX 0x0200 /* sticky bit */ +# define EXT2_S_IRWXU 0x01C0 /* user access rights mask */ +# define EXT2_S_IRUSR 0x0100 /* read */ +# define EXT2_S_IWUSR 0x0080 /* write */ +# define EXT2_S_IXUSR 0x0040 /* execute */ +# define EXT2_S_IRWXG 0x0038 /* group access rights mask */ +# define EXT2_S_IRGRP 0x0020 /* read */ +# define EXT2_S_IWGRP 0x0010 /* write */ +# define EXT2_S_IXGRP 0x0008 /* execute */ +# define EXT2_S_IRWXO 0x0007 /* others access rights mask */ +# define EXT2_S_IROTH 0x0004 /* read */ +# define EXT2_S_IWOTH 0x0002 /* write */ +# define EXT2_S_IXOTH 0x0001 /* execute */ + +#endif diff --git a/modules/x86/modules_conf.cpp b/modules/x86/modules_conf.cpp @@ -2,15 +2,17 @@ # define __MODULE_CONF__ # include <ModuleKeyboard.hpp> # include <ModuleTime.hpp> - +# include <ModuleExt2.hpp> main_module { // Importations Lines import_module(ModuleKeyboard, MODULE_DEVICE | MODULE_KEYBOARD, module_keyboard, "keyboard"); import_module(ModuleTime, MODULE_DEVICE | MODULE_TIME, module_time, "time"); + import_module(ModuleExt2, MODULE_DEVICE | MODULE_FILESYSTEM, module_ext2, "ext2"); // Creations lines reg_module(module_keyboard); reg_module(module_time); + reg_module(module_ext2); } #endif diff --git a/qemu.sh b/qemu.sh @@ -1,2 +1,2 @@ #!/bin/bash -sudo kvm -m 1024 -s -hda ./kern.img -serial /dev/tty -redir tcp:2323::23 -curses +sudo kvm -m 1024 -s -hda ./kern.img -redir tcp:2323::23 -curses