From 0fe64260c0f382de9cc848cc6140085d438ef95d Mon Sep 17 00:00:00 2001 From: xiaoyi1212 Date: Sun, 9 Jun 2024 17:53:48 +0800 Subject: [PATCH] =?UTF-8?q?=20=E4=BF=AE=E5=A4=8DISO9660=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=AF=BB=E5=8F=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fs/iso9660.c | 371 +++++++++++++++----------------- src/include/description_table.h | 1 + src/include/elf.h | 46 ++++ src/include/memory.h | 2 + src/kernel/page.c | 8 +- src/kernel/task.c | 6 +- src/sysapp/shell.c | 4 + 7 files changed, 242 insertions(+), 196 deletions(-) create mode 100644 src/include/elf.h diff --git a/src/fs/iso9660.c b/src/fs/iso9660.c index 9e11f49..4810060 100644 --- a/src/fs/iso9660.c +++ b/src/fs/iso9660.c @@ -6,6 +6,7 @@ bool read_sector(l9660_fs *fs, void *buf, uint32_t sector); #define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos))) #define l9660_telldir(dir) (l9660_tell(&(dir)->file)) +xi#define get_root_dir(vfs) ((l9660_fs_status_t *)(vfs->cache))->root_dir #define SEEK_END L9660_SEEK_END #define SEEK_SET L9660_SEEK_SET @@ -41,77 +42,59 @@ static char gbuf[2048]; #define get_now_dir(vfs) ((l9660_fs_status_t *)(vfs->cache))->now_dir -static char *strchrnul(const char *s, int c) -{ - while (*s) - { + +static char *strchrnul(const char *s, int c) { + while (*s) { if ((*s++) == c) break; } return (char *)s; } -static inline uint16_t -fsectoff(l9660_file - *f) -{ - return f->position % 2048; +static inline uint16_t fsectoff(l9660_file *f) { return f->position % 2048; } + +static inline uint32_t fsector(l9660_file *f) { return f->position / 2048; } + +static inline uint32_t fnextsectpos(l9660_file *f) { +return (f->position + 2047) & ~2047; } -static inline uint32_t -fsector(l9660_file - *f) -{ - return f->position / 2048; -} - -static inline uint32_t -fnextsectpos(l9660_file - *f) -{ - return (f->position + 2047) & ~2047; -} - -l9660_status l9660_openfs(l9660_fs *fs, bool (*read_sector)(l9660_fs *fs, void *buf, uint32_t sector), uint8_t disk_number) -{ - fs->read_sector = read_sector; - fs->disk_number = disk_number; - logkf("fs--- %08x\n",fs->read_sector); +l9660_status l9660_openfs(l9660_fs *fs, + bool (*read_sector)(l9660_fs *fs, void *buf, + uint32_t sector), + uint8_t disk_number) { +fs->read_sector = read_sector; +fs->disk_number = disk_number; #ifndef L9660_SINGLEBUFFER - l9660_vdesc_primary *pvd = PVD(&fs->pvd); +l9660_vdesc_primary *pvd = PVD(&fs->pvd); #else - last_file = NULL; - l9660_vdesc_primary *pvd = PVD(gbuf); +last_file = NULL; + l9660_vdesc_primary *pvd = PVD(gbuf); #endif - uint32_t idx = 0x10; - for (;;) - { - // Read next sector - if (!read_sector(fs, pvd, idx)) - return L9660_EIO; +uint32_t idx = 0x10; +for (;;) { +// Read next sector +if (!read_sector(fs, pvd, idx)) +return L9660_EIO; - // Validate magic - if ( - memcmp(pvd - ->hdr.magic, - "CD001", 5) != 0) - return L9660_EBADFS; +// Validate magic +if (memcmp(pvd->hdr.magic, "CD001", 5) != 0) +return L9660_EBADFS; - if (pvd->hdr.type == 1) - break; // Found PVD - else if (pvd->hdr.type == 255) - return L9660_EBADFS; - } +if (pvd->hdr.type == 1) +break; // Found PVD +else if (pvd->hdr.type == 255) +return L9660_EBADFS; +} #ifdef L9660_SINGLEBUFFER - memcpy(&fs->root_dir_ent, &pvd->root_dir_ent, pvd->root_dir_ent.length); +memcpy(&fs->root_dir_ent, &pvd->root_dir_ent, pvd->root_dir_ent.length); #endif - return L9660_OK; +return L9660_OK; } -l9660_status l9660_fs_open_root(l9660_dir *dir, l9660_fs *fs) -{ +l9660_status l9660_fs_open_root(l9660_dir *dir, l9660_fs *fs) { l9660_file *f = &dir->file; #ifndef L9660_SINGLEBUFFER l9660_dirent *dirent = &PVD(&fs->pvd)->root_dir_ent; @@ -127,35 +110,32 @@ l9660_status l9660_fs_open_root(l9660_dir *dir, l9660_fs *fs) return L9660_OK; } -static l9660_status buffer(l9660_file *f) -{ +static l9660_status buffer(l9660_file *f) { #ifdef L9660_SINGLEBUFFER last_file = f; #endif - logkf("%08x %08x\n",read_sector,f->fs->read_sector); + if (!f->fs->read_sector(f->fs, BUF(f), f->first_sector + f->position / 2048)) return L9660_EIO; else return L9660_OK; } -static l9660_status prebuffer(l9660_file *f) -{ +static l9660_status prebuffer(l9660_file *f) { if (!HAVEBUFFER(f) || (f->position % 2048) == 0) return buffer(f); else return L9660_OK; } -static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char *name, bool isdir) -{ +static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, + const char *name, bool isdir) { l9660_status rv; l9660_dirent *dent = NULL; if ((rv = l9660_seekdir(parent, 0))) return rv; - do - { + do { const char *seg = name; name = strchrnul(name, '/'); size_t seglen = name - seg; @@ -165,14 +145,12 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char seg = "\0"; /* ISO9660 stores ".." as '\1' */ - if (seglen == 2 && seg[0] == '.' && seg[1] == '.') - { + if (seglen == 2 && seg[0] == '.' && seg[1] == '.') { seg = "\1"; seglen = 1; } - for (;;) - { + for (;;) { if ((rv = l9660_readdir(parent, &dent))) return rv; @@ -204,20 +182,17 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char child->first_sector = READ32(dent->sector) + dent->xattr_length; child->length = READ32(dent->size); child->position = 0; - + parent->file.position = 0; if (*name && (dent->flags & DENT_ISDIR) != 0) return L9660_ENOTDIR; parent = (l9660_dir *)child; } while (*name); - if (isdir) - { + if (isdir) { if ((dent->flags & DENT_ISDIR) == 0) return L9660_ENOTDIR; - } - else - { + } else { if ((dent->flags & DENT_ISDIR) != 0) return L9660_ENOTFILE; } @@ -225,33 +200,28 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char return L9660_OK; } -l9660_status l9660_opendirat(l9660_dir *dir, l9660_dir *parent, const char *path) -{ +l9660_status l9660_opendirat(l9660_dir *dir, l9660_dir *parent, + const char *path) { return openat_raw(&dir->file, parent, path, true); } -static inline unsigned aligneven(unsigned v) -{ - return v + (v & 1); -} +static inline unsigned aligneven(unsigned v) { return v + (v & 1); } -l9660_status l9660_readdir(l9660_dir *dir, l9660_dirent **pdirent) -{ +l9660_status l9660_readdir(l9660_dir *dir, l9660_dirent **pdirent) { l9660_status rv; l9660_file *f = &dir->file; -rebuffer: - if (f->position >= f->length) - { + rebuffer: + if (f->position >= f->length) { *pdirent = NULL; + f->position = 0; return L9660_OK; } if ((rv = prebuffer(f))) return rv; char *off = BUF(f) + fsectoff(f); - if (*off == 0) - { + if (*off == 0) { // Padded end of sector f->position = fnextsectpos(f); goto rebuffer; @@ -264,34 +234,31 @@ rebuffer: return L9660_OK; } -l9660_status l9660_openat(l9660_file *child, l9660_dir *parent, const char *name) -{ +l9660_status l9660_openat(l9660_file *child, l9660_dir *parent, + const char *name) { return openat_raw(child, parent, name, false); } /*! Seek the file to \p offset from \p whence */ -l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset) -{ +l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset) { l9660_status rv; uint32_t cursect = fsector(f); - switch (whence) - { - case SEEK_SET: - f->position = offset; - break; + switch (whence) { + case SEEK_SET: + f->position = offset; + break; - case SEEK_CUR: - f->position = f->position + offset; - break; + case SEEK_CUR: + f->position = f->position + offset; + break; - case SEEK_END: - f->position = f->length - offset; - break; + case SEEK_END: + f->position = f->length - offset; + break; } - if (fsector(f) != cursect && fsectoff(f) != 0) - { + if (fsector(f) != cursect && fsectoff(f) != 0) { if ((rv = buffer(f))) return rv; } @@ -299,13 +266,9 @@ l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset) return L9660_OK; } -uint32_t l9660_tell(l9660_file *f) -{ - return f->position; -} +uint32_t l9660_tell(l9660_file *f) { return f->position; } -l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read) -{ +l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read) { l9660_status rv; if ((rv = prebuffer(f))) @@ -324,91 +287,54 @@ l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read) return L9660_OK; } - -bool read_sector(l9660_fs *fs, void *buf, uint32_t sector) -{ - return CDROM_Read(sector,1,buf,fs->disk_number); +char *strdup(const char *s) { + size_t l = strlen(s); + char *d = kmalloc(l + 1); + if (!d) + return NULL; + return memcpy(d, s, l + 1); +} +bool read_sector(l9660_fs *fs, void *buf, uint32_t sector) { + return CDROM_Read(sector, 1, buf, fs->disk_number); } -bool ISO_Check(uint8_t disk_number) -{ +bool ISO_Check(uint8_t disk_number) { unsigned char *buffer = kmalloc(2049); // 假设扇区大小为 2048 字节 bool ok = CDROM_Read(16, 1, buffer, disk_number); - if (buffer[0] == 0x01 && buffer[1] == 'C' && buffer[2] == 'D' && buffer[3] == '0' && - buffer[4] == '0' && buffer[5] == '1') - { + if (buffer[0] == 0x01 && buffer[1] == 'C' && buffer[2] == 'D' && + buffer[3] == '0' && buffer[4] == '0' && buffer[5] == '1') { kfree(buffer); return true; // 是 ISO9660 文件系统 - } - else{ + } else { kfree(buffer); return false; // 不是 ISO9660 文件系统 } } -void ISO_InitFs(struct vfs_t *vfs, uint8_t disk_number) -{ +void ISO_InitFs(struct vfs_t *vfs, uint8_t disk_number) { l9660_fs_status_t *fs_m; - fs_m = (l9660_fs_status_t*) kmalloc(sizeof(l9660_fs_status_t)); + fs_m = (l9660_fs_status_t *)kmalloc(sizeof(l9660_fs_status_t)); fs_m->fs = (l9660_fs *)kmalloc(sizeof(l9660_fs)); vfs->cache = (void *)fs_m; - printf("ISO Load init..."); - l9660_openfs(fs_m->fs,read_sector,disk_number); + l9660_openfs(fs_m->fs, read_sector, disk_number); l9660_fs_open_root(&fs_m->root_dir, fs_m->fs); fs_m->now_dir = fs_m->root_dir; - logkf("%08x\n",vfs->cache); - /* - l9660_file file; - for (;;) { - l9660_dirent *dent; - l9660_readdir(root_dir, &dent); - - if (dent == 0) - break; - - printf("%.*s\n", dent->name_len, dent->name); - } - a = l9660_openat(&file, dir, "fuck.txt"); - if(a) { - printf("failed\n"); - for(;;); - } - for(;;) { - char buf[128]; - size_t read; - l9660_read(&file, buf, 128, &read); - if (read == 0) - break; - for(int i = 0;icache); } -void ISO_CDFile(){} +void ISO_CDFile() {} -vfs_file *ISO_GetFile(char* path1){ -// strtoupper(path1); -// if (strcmp(path1, "/") == 0) { -// return fs_m->root_dir; -// } - return NULL; -} - -void ISO_CopyCache(struct vfs_t *dest, struct vfs_t *src){ +void ISO_CopyCache(struct vfs_t *dest, struct vfs_t *src) { dest->cache = kmalloc(sizeof(l9660_fs_status_t)); memcpy(dest->cache, src->cache, sizeof(l9660_fs_status_t)); } -int ISO_cd(struct vfs_t *vfs, char *dictname){ -// -// strtoupper(dictname); -// +int ISO_cd(struct vfs_t *vfs, char *dictname) { + // + // strtoupper(dictname); + // if (strcmp(dictname, "/") == 0) { while (vfs->path->ctl->all != 0) { kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val)); @@ -418,10 +344,20 @@ int ISO_cd(struct vfs_t *vfs, char *dictname){ get_now_dir(vfs) = fs_m->root_dir; return 1; } - + int free_flag = 0; l9660_dir finfo; - l9660_status a = l9660_opendirat(&finfo,&get_now_dir(vfs),dictname); + l9660_status a; + RE: + a = l9660_opendirat(&finfo, &get_now_dir(vfs), dictname); if (a) { + if (free_flag) { + kfree(dictname); + } else { + dictname = strdup(dictname); + strtoupper(dictname); + free_flag = 1; + goto RE; + } return 0; } get_now_dir(vfs) = finfo; @@ -435,37 +371,64 @@ int ISO_cd(struct vfs_t *vfs, char *dictname){ kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val)); DeleteVal(vfs->path->ctl->all, vfs->path); } - return 1; + if (free_flag) { + kfree(dictname); + } + return 1; } -bool ISO_ReadFile(struct vfs_t *vfs, char *path, char *buffer){ +bool ISO_ReadFile(struct vfs_t *vfs, char *path, char *buffer) { l9660_file file; - l9660_status a = l9660_openat(&file, &get_now_dir(vfs),path); - if(a) { + l9660_status a; + int free_flag = 0; + RE: + a = l9660_openat(&file, &get_now_dir(vfs), path); + if (a) { + if (free_flag) { + kfree(path); + } else { + path = strdup(path); + strtoupper(path); + free_flag = 1; + goto RE; + } return false; // not found } - for(;;) { + for (;;) { size_t read; l9660_read(&file, buffer, 128, &read); if (read == 0) break; buffer += read; } + if (free_flag) { + kfree(path); + } return true; } -List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){ +List *ISO_ListFile(struct vfs_t *vfs, char *dictpath) { l9660_dir finfo; - if(strcmp(dictpath,"") == 0) + int free_flag = 0; + if (strcmp(dictpath, "") == 0) finfo = get_now_dir(vfs); else { - l9660_status a = l9660_opendirat(&finfo,&get_now_dir(vfs),dictpath); + l9660_status a; + RE: + a = l9660_opendirat(&finfo, &get_now_dir(vfs), dictpath); if (a) { + if (free_flag) { + kfree(dictpath); + } else { + dictpath = strdup(dictpath); + strtoupper(dictpath); + free_flag = 1; + goto RE; + } return NULL; } } - List *result = NewList(); for (;;) { l9660_dirent *dent; @@ -474,47 +437,69 @@ List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){ if (dent == 0) break; vfs_file *d = kmalloc(sizeof(vfs_file)); - memclean((void *)d,sizeof(vfs_file)); + memclean((void *)d, sizeof(vfs_file)); int j = 0; - if(memcmp("\0",dent->name,dent->name_len) == 0) { + if (memcmp("\0", dent->name, dent->name_len) == 0) { + if (finfo.file.first_sector == get_root_dir(vfs).file.first_sector) { + kfree(d); + continue; + } d->name[j++] = '.'; d->name[j] = 0; - } else if (memcmp("\1",dent->name,dent->name_len) == 0) { + } else if (memcmp("\1", dent->name, dent->name_len) == 0) { + if (finfo.file.first_sector == get_root_dir(vfs).file.first_sector) { + kfree(d); + continue; + } d->name[j++] = '.'; d->name[j++] = '.'; d->name[j] = 0; - } - else - for(;jname_len;j++) { - if(dent->name[j] == ';') { + } else + for (; j < dent->name_len; j++) { + if (dent->name[j] == ';') { break; } d->name[j] = dent->name[j]; } - d->name[j] = 0; + d->name[j] = 0; d->type = FLE; - if(dent->flags & DENT_ISDIR) { + if (dent->flags & DENT_ISDIR) { d->type = DIR; } else { d->size = READ32(dent->size); } AddVal(d, result); } + if (free_flag) { + kfree(dictpath); + } return result; } int ISO_FileSize(struct vfs_t *vfs, char *filename) { l9660_file file; - l9660_status a = l9660_openat(&file, &get_now_dir(vfs),filename); - if(a) { - return -1; // not found + l9660_status a; + int free_flag = 0; + RE: + a = l9660_openat(&file, &get_now_dir(vfs), filename); + if (a) { + if (free_flag) { + kfree(filename); + } else { + filename = strdup(filename); + strtoupper(filename); + free_flag = 1; + goto RE; + } + return -1; // not found + } + if (free_flag) { + kfree(filename); } return file.length; } - -void init_iso9660() -{ +void init_iso9660() { vfs_t fs; fs.flag = 1; fs.cache = NULL; diff --git a/src/include/description_table.h b/src/include/description_table.h index 1ec240f..844b6a2 100644 --- a/src/include/description_table.h +++ b/src/include/description_table.h @@ -122,6 +122,7 @@ typedef struct tss_table { } tss_entry; void write_tss(int32_t num, uint16_t ss0, uint32_t esp0); +void set_kernel_stack(uintptr_t stack); void gdt_install(); void idt_install(); diff --git a/src/include/elf.h b/src/include/elf.h new file mode 100644 index 0000000..e96e938 --- /dev/null +++ b/src/include/elf.h @@ -0,0 +1,46 @@ +#ifndef CRASHPOWEROS_ELF_H +#define CRASHPOWEROS_ELF_H + +#define ELF_MAGIC 0x464c457f + +#include "common.h" + +/* elf 32 header */ +typedef struct elf32hdr { + uint32_t magic; // equal ELF_MAGIC + char elf[12]; + uint16_t type; + uint16_t machine; + uint32_t version; + uint32_t entry; // program entry + uint32_t phoff; // offset of program header + uint32_t shoff; + uint32_t flags; + uint16_t ehsize; + uint16_t phentsize; + uint16_t phnum; // number of program header + uint16_t shentsize; + uint16_t shnum; + uint16_t shstrndx; +}elf32hdr_t; + +/* proghdr type */ +#define ELF_PROG_LOAD 1 + +/* proghdr flag*/ +#define ELF_PROG_EXEC 0x1 +#define ELF_PROG_WRITE 0x2 +#define ELF_PROG_READ 0x4 + +struct proghdr{ + uint32_t type; + uint32_t off; + uint32_t vaddr; + uint32_t paddr; + uint32_t filesz; + uint32_t memsz; + uint32_t flag; + uint32_t align; +}; + +#endif diff --git a/src/include/memory.h b/src/include/memory.h index f1a2ef9..156d869 100644 --- a/src/include/memory.h +++ b/src/include/memory.h @@ -93,4 +93,6 @@ void alloc_frame_line(page_t *page, unsigned line,int is_kernel, int is_writable void free_frame(page_t *page); +void page_flush(page_directory_t *dir); + #endif //CRASHPOWEROS_MEMORY_H diff --git a/src/kernel/page.c b/src/kernel/page.c index fecd9cb..abd7798 100644 --- a/src/kernel/page.c +++ b/src/kernel/page.c @@ -86,6 +86,12 @@ void free_frame(page_t *page) { } } +void page_flush(page_directory_t *dir){ + asm volatile("invlpg (%0)" ::"r"(&dir->tablesPhysical)); + current_directory = dir; + //asm volatile("mov %0, %%cr3" : : "r"(&dir->physicalAddr)); +} + void switch_page_directory(page_directory_t *dir) { current_directory = dir; asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical)); @@ -200,7 +206,7 @@ void init_page(multiboot_t *mboot) { current_directory = kernel_directory; int i = 0; - while (i < placement_address) { + while (i < placement_address + 0x30000) { // 内核部分对ring3而言可读不可写 | 无偏移页表映射 alloc_frame(get_page(i, 1, kernel_directory), 0, 0); i += 0x1000; diff --git a/src/kernel/task.c b/src/kernel/task.c index 5ed51ba..1328ae6 100644 --- a/src/kernel/task.c +++ b/src/kernel/task.c @@ -2,6 +2,7 @@ #include "../include/common.h" #include "../include/graphics.h" #include "../include/io.h" +#include "../include/description_table.h" struct task_struct *running_proc_head = NULL; struct task_struct *wait_proc_head = NULL; @@ -157,7 +158,8 @@ void change_task_to(struct task_struct *next) { struct task_struct *prev = current; current = next; - switch_page_directory(current->pgd_dir); + page_flush(current->pgd_dir); + set_kernel_stack(current->stack); switch_to(&(prev->context), &(current->context)); } } @@ -172,7 +174,7 @@ int32_t kernel_thread(int (*fn)(void *), void *arg,char* name) { new_task->state = TASK_RUNNABLE; new_task->stack = current; new_task->pid = now_pid++; - new_task->pgd_dir = kernel_directory; + new_task->pgd_dir = clone_directory(kernel_directory) ; new_task->name = name; diff --git a/src/sysapp/shell.c b/src/sysapp/shell.c index 7ab87d7..921a411 100644 --- a/src/sysapp/shell.c +++ b/src/sysapp/shell.c @@ -6,7 +6,9 @@ #include "../include/cmos.h" #include "../include/vdisk.h" #include "../include/vfs.h" +#include "../include/common.h" #include "../include/sb16.h" +#include "../include/elf.h" extern Queue *key_char_queue; extern vdisk vdisk_ctl[10]; @@ -239,6 +241,8 @@ void cmd_type(int argc,char ** argv){ printf("%s",buffer); else printf("Cannot read file.\n"); + + kfree(buffer); print("\n"); }