diff --git a/fs/namei.c b/fs/namei.c index 00c92d064155ca51bf05a2c8520c3f9efb708e69..f68fb6f324f39897d122c085405afdfd58d5c7af 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -20,6 +20,7 @@ static struct m_inode * _namei(const char * filename, struct m_inode * base, static int permission(struct m_inode * inode,int mask) { int mode = inode->i_mode; + if (inode->i_dev && !inode->i_nlinks) return 0; else if (current->euid==inode->i_uid) @@ -199,7 +200,7 @@ static struct m_inode * get_dir(const char * pathname, struct m_inode * inode) { inode->i_count++; } if ((c=get_fs_byte(pathname))=='/') { - //iput(inode); + iput(inode); inode = current->root; pathname++; inode->i_count++; @@ -208,7 +209,7 @@ static struct m_inode * get_dir(const char * pathname, struct m_inode * inode) { while (1) { thisname = pathname; if (!S_ISDIR(inode->i_mode) || !permission(inode,MAY_EXEC)) { - // iput(inode); + iput(inode); return NULL; } for(namelen=0;(c=get_fs_byte(pathname++))&&(c!='/');namelen++) @@ -217,7 +218,7 @@ static struct m_inode * get_dir(const char * pathname, struct m_inode * inode) { return inode; if (!(bh = find_entry(&inode,thisname,namelen,&de))) { - // iput(inode); + iput(inode); return NULL; } @@ -225,7 +226,7 @@ static struct m_inode * get_dir(const char * pathname, struct m_inode * inode) { brelse(bh); dir = inode; if (!(inode = iget(dir->i_dev,inr))) { - //iput(dir); + iput(dir); return NULL; } } diff --git a/kernel/Makefile b/kernel/Makefile index bd35202dc2f2cf9ab69e93a62870ec08f56ec938..831109424ccb8ba15b6e19664079fe85d7474bd2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,5 +1,5 @@ GCC := gcc -USE_DEBUG := -DDEBUG=2 +USE_DEBUG := CCFLAG := -I../include -nostdinc -ffreestanding -Wall -fomit-frame-pointer -fno-pic -fno-stack-protector -c -m32 $(USE_DEBUG) LDFLAG := -Ttext 0x0 -s --oformat binary -m elf_i386 INCDIR := ../include diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c index 319b7ac24cdf86fd567e6d106f9de7fdc3560ea4..19bc126e3fcc69c52465ce4ec41a1dc4c0179397 100644 --- a/kernel/chr_drv/console.c +++ b/kernel/chr_drv/console.c @@ -170,7 +170,7 @@ static void scrup() { } } -static void lf() { +void lf() { if (y + 1 < bottom) { y++; pos += video_size_row; @@ -503,6 +503,19 @@ void con_write(struct tty_struct* tty) { case '8': restore_cur(); break; + case '(': case ')': + state = ESsetgraph; + break; + case 'P': + state = ESsetterm; + break; + case '#': + state = -1; + break; + case 'c': + top = 0; + bottom = video_num_lines; + break; } break; case ESsquare: @@ -610,6 +623,14 @@ void con_write(struct tty_struct* tty) { break; } break; + case ESsetterm: + state = ESnormal; + if (c == 'S') { + } else if (c == 'L') + ; + else if (c == 'l') + ; + break; } } diff --git a/kernel/main.c b/kernel/main.c index 0725fa1e5f861594cc1e9ea1a04b4948b4b421f0..68fd33862e41c627d4c82a28c0f32b8ca75c1af0 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -171,9 +171,10 @@ static void easy_shell() { static void run_sh() { int pid; + printf("ready to fork shell\n"); if (!(pid=fork())) { - printf("read to start shell\n"); - execve("/bin/sh", argv,envp); + printf("ready to start shell\n"); + execve("/et", argv,envp); } } @@ -185,7 +186,9 @@ void init() { (void) dup(0); (void) dup(0); - //run_sh(); + printf("before run shell\n"); + run_sh(); + return; //easy_shell(); printf("Free mem: %d bytes\n\r",memory_end-main_memory_start); @@ -210,7 +213,7 @@ void init() { if (!pid) { close(0);close(1);close(2); setsid(); - (void) open("/dev/tty0",O_RDWR,0); + (void) open("/dev/tty1",O_RDWR,0); (void) dup(0); (void) dup(0); _exit(execve("/bin/sh",argv,envp)); diff --git a/kernel/printk.c b/kernel/printk.c index 63f584a05e2573fb90f296b208131669df57a77a..c0bbd46b7fd25d507358853aa266e14eaeb0f2c2 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -30,18 +30,38 @@ int printk(const char* fmt, ...) { } void print_sys(int index) { +#ifndef DEBUG + return; +#endif + int i; +#if DEBUG != 2 int filter[] = { + 1, 2, /* fork */ - 3, 4, 5, 6, + 4, 5, 6, 7, /* waitpid */ 12, 18, 27, /* alarm */ + 28, 29, 36, /* sync */ - 45, 48, 54, 80, + 45, 48, 54, + 63, + 80, 84, /* lstat */ }; +#else + int filter[] = { + 1, 2, 3, + 45, + 48, + 54, + 27, + 36, + 29 + }; +#endif for (i = 0; i < sizeof(filter) / sizeof(int); i++) { if (index == filter[i]) diff --git a/kernel/traps.c b/kernel/traps.c index 62cc6b82828e18780aba8a0c0f0e7ebee227b51e..1fba8bcd22f40b920fb6504f5c91f5ad60bae975 100644 --- a/kernel/traps.c +++ b/kernel/traps.c @@ -70,7 +70,8 @@ static void die(char* str, long esp_ptr, long nr) { printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); printk("\n\r"); - do_exit(11); + //do_exit(11); + for(;;); } void do_double_fault(long esp, long error_code) { diff --git a/tools/build.c b/tools/build.c index 6cf7bd35cbbd97acb82622210b5b6d4ba96dc343..df7cf9d2ccd790bbb00366c7b82358f4666c73e9 100644 --- a/tools/build.c +++ b/tools/build.c @@ -12,8 +12,8 @@ #define SYS_SIZE 0x2000 -#define DEFAULT_MAJOR_ROOT 3 -#define DEFAULT_MINOR_ROOT 1 +#define DEFAULT_MAJOR_ROOT 2 +#define DEFAULT_MINOR_ROOT 29 #define SETUP_SECTS 4 diff --git a/tools/mkfs/Makefile b/tools/mkfs/Makefile index e17a42e9206770acfa605b9e16f4b51dc5e49ba7..2de45c9fbc3ac81f35d0aeb193111a3a0a317c0a 100644 --- a/tools/mkfs/Makefile +++ b/tools/mkfs/Makefile @@ -1,5 +1,5 @@ -mfs: mfs.cpp utils.cpp - g++ -o mfs mfs.cpp utils.cpp +mfs: mfs.cpp utils.cpp minixfs.cpp + g++ -o mfs -g mfs.cpp utils.cpp minixfs.cpp clean: -rm mfs diff --git a/tools/mkfs/common.hpp b/tools/mkfs/common.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8890436233c95b312529343479cd16d726787e99 --- /dev/null +++ b/tools/mkfs/common.hpp @@ -0,0 +1,26 @@ +#ifndef _COMMON_HPP +#define _COMMON_HPP + +#define BLOCKS 1440 + +#define UPPER(size,n) ((size+((n)-1))/(n)) + +#define INODE_SIZE (sizeof(struct d_inode)) +#define INODE_BLOCKS UPPER(INODES,INODES_PER_BLOCK) +#define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE) + +#define BITS_PER_BLOCK (BLOCK_SIZE<<3) + +#define INODES (_super_blk->s_ninodes) +#define ZONESIZE (_super_blk->s_log_zone_size) +#define ZONES (_super_blk->s_nzones) +#define MAXSIZE (_super_blk->s_max_size) +#define IMAPS (_super_blk->s_imap_blocks) +#define ZMAPS (_super_blk->s_zmap_blocks) +#define MAGIC (_super_blk->s_magic) +#define FIRSTZONE (_super_blk->s_firstdatazone) + +#define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS) + +#endif + diff --git a/tools/mkfs/copy_file.cpp b/tools/mkfs/copy_file.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tools/mkfs/mfs.cpp b/tools/mkfs/mfs.cpp index 4095f78de8d85cad2769513fd1c15eb9bcbce4e2..17d55878fd65413b1a5a406f2c97e5b00be6033e 100644 --- a/tools/mkfs/mfs.cpp +++ b/tools/mkfs/mfs.cpp @@ -1,11 +1,9 @@ -#include "mfs.h" - #include #include #include #include -#define BLOCKS 1440 +#include "minixfs.hpp" Mode mode; @@ -45,9 +43,14 @@ d_inode* root = NULL; char* filename = NULL; char* dir_name = NULL; + +char* src_img = NULL; char* src_file = NULL; +char* tgt_img = NULL; +char* tgt_file = NULL; char* target_name = NULL; +char* extract_name = NULL; #define bitop(name,op) \ static inline int name(char * addr,unsigned int nr) \ @@ -248,7 +251,9 @@ FILE* read_file() { } for (int i = FIRSTZONE; i < BLOCKS; i++) { - images[i] = new char[BLOCK_SIZE]; + if (!images[i]) + images[i] = new char[BLOCK_SIZE]; + if (BLOCK_SIZE != fread(images[i], sizeof(char), BLOCK_SIZE, img_file)) { printf("error when read blocks, %d\n", i); } @@ -289,18 +294,6 @@ m_inode* namei(const char* dir_name) { return pwd; } -void list_dir() { - m_inode* inode = namei(dir_name); - char* pwd_block = get_block(bmap(inode->p, 0)); - - for (int i = 0; i < inode->p->i_size / sizeof(struct dir_entry); i++) { - struct dir_entry* dir = ((struct dir_entry*)pwd_block) + i; - printf("%d, %s\n", dir->inode, dir->name); - } - - delete inode; -} - int find_empty_inode() { int i = 0, j = 0, k = 0; for (i = 0; i < IMAPS; i++) { @@ -362,9 +355,9 @@ void write_image() { } m_inode* create_new_file(long length) { - char* parent_name = get_dir_name(dir_name); + char* parent_name = get_dir_name(tgt_file); m_inode* parent = namei(parent_name); - const char* dname = get_entry_name(dir_name); + const char* dname = get_entry_name(tgt_file); printf("new file: %s\n", dname); m_inode* ndnode = get_new_file_inode(length); @@ -403,8 +396,8 @@ int write_file(const char* src_file, const char* dst_file) { FILE* srcf = fopen(src_file, "r"); m_inode* finode = create_new_file(file_length(srcf)); - dir_name = get_dir_name(dir_name); - list_dir(); + dir_name = get_dir_name(tgt_file); + //list_dir(); int total = 0; for (int i = 0; i < UPPER(finode->p->i_size, BLOCK_SIZE); i++) { @@ -456,7 +449,7 @@ int make_dir() { } dir_name = parent_name; - list_dir(); + //list_dir(); delete[] dname; delete parent; @@ -491,16 +484,51 @@ void setup_image() { } void init_fs() { - setup_table(); - setup_image(); - img_file = fopen(filename, "w+"); + FileSystem* fs = new FileSystem(filename, true); + fs->init_fs(); + fs->write_image(); + delete fs; +} - // create an empty dir, root. - delete get_new_dir_inode(NULL); - write_image(); +void extract_file() { + read_file(); + m_inode* mi = namei(extract_name); + if (mi == NULL) { + printf("Can not find file %s\n", extract_name); + return; + } - free_images(); - fclose(img_file); + printf("file mode is %ud\n", mi->p->i_size); + printf("file nlinks is %d\n", mi->p->i_nlinks); + if (mi->p->i_size == 0) { + printf("file %s is empty.\n", extract_name); + return; + } + + FILE* extract = fopen(target_name, "w+"); + for (int i = 0; i < mi->p->i_size / BLOCK_SIZE; i++) { + int index = bmap(mi->p, i); + if (index == 0) + continue; + + if (fwrite(images[index], sizeof(char), BLOCK_SIZE, extract) != BLOCK_SIZE) { + printf("Error: write failed in extacting file"); + fclose(extract); + return; + } + } + + fclose(extract); +} + +int copy_file() { + FileSystem *sfs = new FileSystem(src_img); + FileSystem *tfs = new FileSystem(tgt_img); + sfs->copy_to(tfs, src_file, tgt_file); + tfs->write_image(); + + delete sfs; + delete tfs; } int main(int argc, char** argv) { @@ -522,14 +550,37 @@ int main(int argc, char** argv) { mode = LIST; } else if (t[1] == 'c') { - argc--; - src_file = argv[i++]; - mode = COPY; + if (t[2] == 'p') { + argc--; + src_file = argv[i++]; + mode = COPY_FILE; + } + else { + argc--; + src_file = argv[i++]; + mode = COPY; + } + } + else if (t[1] == 's') { + if (t[2] == 'f') { + argc--; + src_img = argv[i++]; + mode = COPY_FILE; + } + else { + argc--; + src_file = argv[i++]; + } } else if (t[1] == 't') { - argc--; - dir_name = argv[i++]; - mode = COPY; + if (t[2] == 'f') { + argc--; + tgt_img = argv[i++]; + } + else { + argc--; + tgt_file = argv[i++]; + } } else if (t[1] == 'm') { argc--; @@ -543,6 +594,13 @@ int main(int argc, char** argv) { argc--; target_name = argv[i++]; } + else if (t[1] == 'e') { + if (t[2] == 'x') { + argc--; + extract_name = argv[i++]; + mode = EXTRACT; + } + } } else { filename = t; @@ -553,8 +611,9 @@ int main(int argc, char** argv) { return 0; } else if (mode == LIST) { - read_file(); - list_dir(); + FileSystem* fs = new FileSystem(filename); + fs->list_dir(dir_name); + delete fs; return 0; } else if (mode == COPY) { @@ -568,6 +627,12 @@ int main(int argc, char** argv) { else if (mode == INIT) { init_fs(); } + else if (mode == EXTRACT) { + extract_file(); + } + else if (mode == COPY_FILE) { + copy_file(); + } return 0; diff --git a/tools/mkfs/mfs.h b/tools/mkfs/mfs.h index 3e92ed1e475adc0ef75e9c01dde3759812263a1d..a8845b088863799fff4e06faa5a603ff5554187c 100644 --- a/tools/mkfs/mfs.h +++ b/tools/mkfs/mfs.h @@ -13,6 +13,7 @@ enum Mode { LIST, EXTRACT, COPY, + COPY_FILE, MAKE_DIR, INIT, }; @@ -75,6 +76,9 @@ public: unsigned short i_num; m_inode(d_inode* dp, unsigned short num): p(dp), i_num(num) {} + ~m_inode() { + p = NULL; + } }; struct file { @@ -146,7 +150,7 @@ extern int sync_dev(int dev); extern struct super_block * get_super(int dev); char* get_dir_name(char* full_name); -const char* get_entry_name(char* full_name); +char* get_entry_name(char* full_name); void free_strings(char** dirs); char** split(const char* name); long file_length(FILE* f); diff --git a/tools/mkfs/minixfs.cpp b/tools/mkfs/minixfs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2825c032ca8cd62178bcb8cd286132f9d1c38894 --- /dev/null +++ b/tools/mkfs/minixfs.cpp @@ -0,0 +1,423 @@ +#include +#include +#include + +#include "minixfs.hpp" + +#define bitop(name,op) \ +static inline int name(char * addr,unsigned int nr) \ +{ \ + int __res; \ + __asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \ + :"=g" (__res) \ + :"r" (nr),"m" (*(addr)),"0" (0)); \ + return __res; \ +} + +bitop(bit,"") +bitop(setbit,"s") +bitop(clrbit,"r") + +#define mark_inode(x) (setbit(_inode_map,(x))) +#define unmark_inode(x) (clrbit(_inode_map,(x))) + +#define mark_zone(x) (setbit(_zone_map,(x)-FIRSTZONE+1)) +#define unmark_zone(x) (clrbit(_zone_map,(x)-FIRSTZONE+1)) + +FileSystem::FileSystem(char* img_name, bool is_create) { + image_name = img_name; + for (int i = 0; i < BLOCKS; i++) { + _images[i] = NULL; + } + _super_blk = NULL; + _inode_map = NULL; + _zone_map = NULL; + + load_image(is_create); +} + +int FileSystem::read_block(FILE* f, int block) { + if (_images[block] == NULL) { + _images[block] = new char[BLOCK_SIZE]; + } + + if (fread(_images[block], sizeof(char), BLOCK_SIZE, f) != BLOCK_SIZE) { + printf("read file error, block is %d\n", block); + return -1; + } + + return 0; +} + +int FileSystem::load_image(bool is_create) { + if (is_create) { + for (int i = 0; i < BLOCKS; i++) { + _images[i] = new char[BLOCK_SIZE]; + } + setup_super_block(); + setup_map(); + return 0; + } + + FILE* f = fopen(image_name, "r+"); + for (int i = 0; i < BLOCKS; i++) { + if (read_block(f, i) != 0) { + release_images(); + fclose(f); + return -1; + } + } + fclose(f); + + _super_blk = (super_block*)_images[1]; + _inode_map = _images[2]; + _zone_map = _images[2 + IMAPS]; + _inode_buffer = _images[2 + IMAPS + ZMAPS]; + + _root = iget(ROOT_INO); + + return 0; +} + +void FileSystem::release_images() { + for (int i = 0; i < BLOCKS; i++) { + if (i >= 4 && i < 10) + continue; + if (_images[i]) { + delete[] _images[i]; + _images[i] = NULL; + } + } +} + +m_inode* FileSystem::namei(char* dir_name) { + assert(dir_name[0] == '/'); + char** dirs = split(dir_name); + char** dir_list = dirs; + + m_inode* pwd = new m_inode(_root, 1); + + while (*dir_list) { + m_inode* old = pwd; + pwd = find_entry(pwd, *dir_list); + delete old; + dir_list++; + } + + free_strings(dirs); + return pwd; +} + +m_inode* FileSystem::find_entry(m_inode* pwd, char* name) { + char* pwd_block = get_block(bmap(pwd->p, 0)); + + for (int i = 0; i < pwd->p->i_size / sizeof(struct dir_entry); i++) { + struct dir_entry* dir = ((struct dir_entry*)pwd_block) + i; + if (strcmp(dir->name, name) == 0) { + return new m_inode(iget(dir->inode), dir->inode); + } + } + return NULL; +} + +char * FileSystem::get_block(int nblock) { + return _images[nblock]; +} + +unsigned short FileSystem::_bmap(struct d_inode* inode, int n, bool is_create) { + char* ind; + if (n < 7) { + if (is_create && !inode->i_zone[n]) { + inode->i_zone[n] = get_new_block(); + } + return inode->i_zone[n]; + } + + n -= 7; + if (n < 512) { + if (is_create && !inode->i_zone[7]) { + inode->i_zone[7] = get_new_block(); + } + ind = get_block(inode->i_zone[7]); + if (is_create && !((unsigned short*)ind)[n]) + ((unsigned short*)ind)[n] = get_new_block(); + + return *(((unsigned short*)ind) + n); + } + + n -= 512; + if (is_create && !inode->i_zone[8]) + inode->i_zone[8] = get_new_block(); + + ind = get_block(inode->i_zone[8]); + + if (is_create && !((unsigned short*)ind)[n>>9]) + ((unsigned short*)ind)[n>>9] = get_new_block(); + + ind = get_block(*(((unsigned short*)ind) + (n >> 9))); + + if (!(*(((unsigned short*)ind) + (n & 511)))) { + *(((unsigned short*)ind) + (n & 511)) = get_new_block(); + } + + return *(((unsigned short*)ind) + (n & 511)); +} + +unsigned short FileSystem::bmap(struct d_inode* inode, int n) { + _bmap(inode, n, false); +} + +unsigned short FileSystem::create_block(struct d_inode* inode, int n) { + _bmap(inode, n, true); +} + +unsigned short FileSystem::get_new_block() { + int i = 0, j = 0, k = 0; + for (i = 0; i < ZMAPS; i++) { + for (j = 0; j < BLOCK_SIZE; j++) { + char bitmap = _zone_map[i * BLOCK_SIZE + j]; + if ((bitmap & 0xff) < 0xff) { + for (k = 0; k < 8; k++) { + if (((1 << k) & bitmap) == 0) { + _zone_map[i*BLOCK_SIZE + j] |= (1 << k); + goto found; + } + } + } + } + } + +found: + return (unsigned short)(i * BLOCK_SIZE * 8 + j * 8 + k) + FIRSTZONE - 1; +} + +struct d_inode* FileSystem::iget(int nr) { + int inode_block = (nr - 1) / INODES_PER_BLOCK; + int index_in_block = (nr - 1) % INODES_PER_BLOCK; + + return (struct d_inode*)(_inode_buffer + inode_block * BLOCK_SIZE + + index_in_block * sizeof(struct d_inode)); +} + +void FileSystem::list_dir(char* dir_name) { + m_inode* inode = namei(dir_name); + char* pwd_block = get_block(bmap(inode->p, 0)); + + for (int i = 0; i < inode->p->i_size / sizeof(struct dir_entry); i++) { + struct dir_entry* dir = ((struct dir_entry*)pwd_block) + i; + printf("%d, %s\n", dir->inode, dir->name); + } + + delete inode; +} + +void FileSystem::init_fs() { + // create an empty dir, root. + delete get_new_dir_inode(NULL); +} + +FileSystem::~FileSystem() { + //release_images(); +} + +void FileSystem::setup_map() { + _inode_map = _images[2]; + _zone_map = _images[2 + IMAPS]; + memset(_inode_map,0xff, IMAPS * BLOCK_SIZE); + memset(_zone_map, 0xff, ZMAPS * BLOCK_SIZE); + + _inode_buffer = _images[2 + IMAPS + ZMAPS]; + memset(_inode_buffer, 0, INODE_BUFFER_SIZE); + + for (int i = FIRSTZONE ; ii_mode = I_DIRECTORY | 0777; + inode->i_nlinks = 2; + inode->i_size = 2 * sizeof(struct dir_entry); + inode->i_zone[0] = get_new_block(); + dir_entry* de = (struct dir_entry*)_images[inode->i_zone[0]]; + de->inode = nr; + strncpy(de->name, ".", NAME_LEN); + + de++; + de->inode = parent ? parent->i_num : nr; + strncpy(de->name, "..", NAME_LEN); + + return new m_inode(inode, nr); +} + +int FileSystem::find_empty_inode() { + int i = 0, j = 0, k = 0; + for (i = 0; i < IMAPS; i++) { + for (j = 0; j < BLOCK_SIZE; j++) { + char bitmap = _inode_map[i * BLOCK_SIZE + j]; + if ((bitmap & 0xff) < 0xff) { + for (k = 0; k < 8; k++) { + if (((1 << k) & bitmap) == 0) { + _inode_map[i*BLOCK_SIZE + j] |= (1 << k); + goto found; + } + } + } + } + } + +found: + return i * BLOCK_SIZE * 8 + j * 8 + k; +} + +void FileSystem::copy_to(FileSystem* tfs, char* sfile, char* tfile) { + m_inode* smi = namei(sfile); + char* parent_name = get_dir_name(tfile); + tfs->make_dir(parent_name); + tfs->create_new_file(tfile, smi->p->i_size); + + m_inode* tmi = tfs->namei(tfile); + + if (tmi == NULL) { + tmi = tfs->get_new_dir_inode(NULL); + } + + memcpy(tmi->p, smi->p, sizeof(d_inode)); + + int block = 0; + for (int i = 0; i < smi->p->i_size / BLOCK_SIZE; i++) { + int index = bmap(smi->p, i); + if (index == 0) + continue; + + memcpy(get_block(index), + tfs->get_block(tfs->create_block(tmi->p, block++)), BLOCK_SIZE); + } +} + +int FileSystem::make_dir(char* dir_name) { + char* parent_name = get_dir_name(dir_name); + m_inode* parent = namei(parent_name); + char* dname = get_entry_name(dir_name); + printf("mkdir: %s\n", dname); + + m_inode* ndnode = get_new_dir_inode(parent); + + char* pwd_block = get_block(bmap(parent->p, 0)); + struct dir_entry* dir = (struct dir_entry*)pwd_block; + + int i = 0; + for (i = 0; i < parent->p->i_size / sizeof(struct dir_entry); i++) { + if (!dir->inode) { + dir->inode = ndnode->i_num; + strncpy(dir->name, dname, NAME_LEN); + break; + } + + if ((char*)dir > pwd_block + BLOCK_SIZE) { + pwd_block = get_block(create_block(parent->p, i / DIR_ENTRIES_PER_BLOCK)); + dir = (struct dir_entry*)pwd_block; + } + + dir++; + } + + if (i * sizeof(struct dir_entry) == parent->p->i_size) { + parent->p->i_size = (i + 1) * sizeof(struct dir_entry); + dir->inode = ndnode->i_num; + strncpy(dir->name, dname, NAME_LEN); + } + + list_dir(parent_name); + + delete[] dname; + delete parent; + delete ndnode; + + return 0; +} + +m_inode* FileSystem::get_new_file_inode(long length) { + int nr = find_empty_inode(); + d_inode* inode = iget(nr); + inode->i_size = (unsigned int)length; + for (int i = 0; i < UPPER(inode->i_size, BLOCK_SIZE); i++) { + create_block(inode, i); + } + inode->i_mode = I_REGULAR | 0777; + + return new m_inode(inode, nr); +} + +m_inode* FileSystem::create_new_file(char* dir_name, long length) { + char* parent_name = get_dir_name(dir_name); + m_inode* parent = namei(parent_name); + char* dname = get_entry_name(dir_name); + printf("new file: %s\n", dname); + + m_inode* ndnode = get_new_file_inode(length); + + char* pwd_block = get_block(bmap(parent->p, 0)); + struct dir_entry* dir = (struct dir_entry*)pwd_block; + + int i = 0; + for (i = 0; i < parent->p->i_size / sizeof(struct dir_entry); i++) { + if (!dir->inode) { + dir->inode = ndnode->i_num; + strncpy(dir->name, dname, NAME_LEN); + break; + } + + if ((char*)dir > pwd_block + BLOCK_SIZE) { + pwd_block = get_block(bmap(parent->p, i / DIR_ENTRIES_PER_BLOCK)); + dir = (struct dir_entry*)pwd_block; + } + + dir++; + } + + if (i * sizeof(struct dir_entry) == parent->p->i_size) { + parent->p->i_size = (i + 1) * sizeof(struct dir_entry); + dir->inode = ndnode->i_num; + strncpy(dir->name, dname, NAME_LEN); + } + + return ndnode; +} + diff --git a/tools/mkfs/minixfs.hpp b/tools/mkfs/minixfs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..48dc088bc641cc8d1379d43446fa78671cdffe38 --- /dev/null +++ b/tools/mkfs/minixfs.hpp @@ -0,0 +1,57 @@ +#ifndef _MINIX_FS +#define _MINIX_FS + +#include "mfs.h" +#include "common.hpp" + +class FileSystem { +private: + char* _images[BLOCKS]; + char* image_name; + + super_block* _super_blk; + char* _inode_map; + char* _zone_map; + + char* _inode_buffer; + + d_inode* _root; + + int load_image(bool is_create); + void release_images(); + int read_block(FILE* f, int block); + + + // bitmap + int find_empty_inode(); + unsigned short get_new_block(); + + // inode + d_inode* iget(int nr); + m_inode* find_entry(m_inode* pwd, char* name); + + unsigned short _bmap(struct d_inode* inode, int n, bool is_create); + unsigned short bmap(struct d_inode* inode, int n); + + void setup_super_block(); + void setup_map(); + +public: + FileSystem(char* img_name, bool is_create = false); + ~FileSystem(); + + void list_dir(char* dir_name); + void init_fs(); + void write_image(); + void copy_to(FileSystem* tfs, char* sfile, char* tfile); + + m_inode* namei(char* dir_name); + char * get_block(int nblock); + unsigned short create_block(struct d_inode* inode, int n); + m_inode* get_new_dir_inode(m_inode* parent); + m_inode* get_new_file_inode(long length); + int make_dir(char* dir_name); + m_inode* create_new_file(char* dir_name, long length); +}; + +#endif diff --git a/tools/mkfs/utils.cpp b/tools/mkfs/utils.cpp index 31728c1b0d26764a4adf994150cd5627c7792ec7..cbd524eba91830336bee7126620a366c456d5d43 100644 --- a/tools/mkfs/utils.cpp +++ b/tools/mkfs/utils.cpp @@ -49,6 +49,8 @@ char** split(const char* name) { } p++; } + if (array[j]) + array[j][i] = '\0'; return array; } @@ -89,7 +91,7 @@ char* get_dir_name(char* full_name) { return d; } -const char* get_entry_name(char* full_name) { +char* get_entry_name(char* full_name) { char* p = full_name; int len = strlen(full_name); int dir_len = 0; diff --git a/tools/tcc/linkerscript/a.out.lds b/tools/tcc/linkerscript/a.out.lds index 9d430566b45872b6a97193c39a3f6f35d1ae9601..34e25bd3bab31f4759e2e40e954ab400423d9086 100644 --- a/tools/tcc/linkerscript/a.out.lds +++ b/tools/tcc/linkerscript/a.out.lds @@ -4,7 +4,7 @@ SECTIONS . = 0x0; .text : AT(0x400) { PROVIDE(.text_begin = .); - *(.text) + *(.text); PROVIDE(.text_real_end = .); } .data ALIGN(0x400) : { @@ -39,7 +39,7 @@ SECTIONS LONG(.datasize) LONG(.bsssize) LONG(0) - LONG(0) + LONG(_start) LONG(0) } /DISCARD/ : { *(.eh_frame) *(.comment) *(.rel.eh_frame) *(.note.GNU-stack) }