diff --git a/kernel/filesystem/VFS/VFS.h b/kernel/filesystem/VFS/VFS.h index bc37000b..e26e7794 100644 --- a/kernel/filesystem/VFS/VFS.h +++ b/kernel/filesystem/VFS/VFS.h @@ -24,7 +24,7 @@ struct vfs_superblock_t *vfs_root_sb = NULL; /** * @brief 目录项的属性 - * + * */ #define VFS_ATTR_FILE (1UL << 0) #define VFS_ATTR_DIR (1UL << 1) @@ -73,7 +73,7 @@ struct vfs_index_node_t /** * @brief 文件描述符 - * + * */ struct vfs_file_t { @@ -95,9 +95,9 @@ struct vfs_filesystem_type_t struct vfs_super_block_operations_t { - void (*write_superblock)(struct vfs_superblock_t *sb); + void (*write_superblock)(struct vfs_superblock_t *sb); // 将超级块信息写入磁盘 void (*put_superblock)(struct vfs_superblock_t *sb); - void (*write_inode)(struct vfs_index_node_t *inode); + void (*write_inode)(struct vfs_index_node_t *inode); // 将inode信息写入磁盘 }; /** @@ -153,7 +153,6 @@ uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs); */ struct vfs_superblock_t *vfs_mount_fs(char *name, void *DPTE, uint8_t DPT_type, void *buf, int8_t ahci_ctrl_num, int8_t ahci_port_num, int8_t part_num); - /** * @brief 按照路径查找文件 * diff --git a/kernel/filesystem/fat32/fat32.c b/kernel/filesystem/fat32/fat32.c index 8241c237..e5135bff 100644 --- a/kernel/filesystem/fat32/fat32.c +++ b/kernel/filesystem/fat32/fat32.c @@ -49,7 +49,7 @@ uint32_t fat32_read_FAT_entry(fat32_sb_info_t *fsbi, uint32_t cluster) // 计算每个扇区内含有的FAT表项数 // FAT每项4bytes uint32_t fat_ent_per_sec = (fsbi->bytes_per_sec >> 2); // 该值应为2的n次幂 - + uint32_t buf[256]; memset(buf, 0, fsbi->bytes_per_sec); @@ -551,7 +551,7 @@ long fat32_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) /** * @brief 从fat32文件系统读取数据 - * + * * @param file_ptr 文件描述符 * @param buf 输出缓冲区 * @param count 要读取的字节数 @@ -570,7 +570,7 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po // kdebug("fsbi->bytes_per_clus=%d", fsbi->bytes_per_clus); // clus offset in file - uint64_t total_clus_of_file = (*position) / fsbi->bytes_per_clus; + uint64_t clus_offset_in_file = (*position) / fsbi->bytes_per_clus; // bytes offset in clus uint64_t bytes_offset = (*position) % fsbi->bytes_per_clus; @@ -578,7 +578,7 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po return -EFAULT; // find the actual cluster on disk of the specified position - for (int i = 0; i < total_clus_of_file; ++i) + for (int i = 0; i < clus_offset_in_file; ++i) cluster = fat32_read_FAT_entry(fsbi, cluster); // 如果需要读取的数据边界大于文件大小 @@ -615,7 +615,7 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po if (((uint64_t)buf) < USER_MAX_LINEAR_ADDR) copy_to_user(buf, tmp_buffer + bytes_offset, step_trans_len); else - memcpy(buf, tmp_buffer, step_trans_len); + memcpy(buf, tmp_buffer + bytes_offset, step_trans_len); bytes_remain -= step_trans_len; buf += step_trans_len; @@ -628,14 +628,174 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po kfree(tmp_buffer); - if(!bytes_remain) + if (!bytes_remain) retval = count; return retval; } -// todo: write + +/** + * @brief 在磁盘中寻找一个空闲的簇 + * + * @param fsbi fat32超级块信息结构体 + * @return uint64_t 空闲簇号(找不到则返回0) + */ +uint64_t fat32_find_available_cluster(fat32_sb_info_t *fsbi) +{ + uint64_t sec_per_fat = fsbi->sec_per_FAT; + + // 申请1扇区的缓冲区 + uint32_t *buf = (uint32_t *)kmalloc(fsbi->bytes_per_sec, 0); + int ent_per_sec = (fsbi->bytes_per_sec >> 2); + for (int i = 0; i < sec_per_fat; ++i) + { + memset(buf, 0, fsbi->bytes_per_sec); + + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + i, 1, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); + // 依次检查簇是否空闲 + for (int j = 0; j < ent_per_sec; ++j) + { + // 找到空闲簇 + if ((buf[j] & 0x0fffffff) == 0) + return i * ent_per_sec + j; + } + } + return 0; +} + +/** + * @brief 向fat32文件系统写入数据 + * + * @param file_ptr 文件描述符 + * @param buf 输入写入的字节数 + * @param position 文件指针位置 + * @return long 执行成功:传输的字节数量 执行失败:错误码(小于0) + */ long fat32_write(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *position) { + struct fat32_inode_info_t *finode = (struct fat32_inode_info_t *)file_ptr->dEntry->dir_inode->private_inode_info; + fat32_sb_info_t *fsbi = (fat32_sb_info_t *)(file_ptr->dEntry->dir_inode->sb->private_sb_info); + + // First cluster num of the file + uint64_t cluster = finode->first_clus; + int64_t flags = 0; + + kdebug("fsbi->bytes_per_clus=%d", fsbi->bytes_per_clus); + // clus offset in file + uint64_t clus_offset_in_file = (*position) / fsbi->bytes_per_clus; + // bytes offset in clus + uint64_t bytes_offset = (*position) % fsbi->bytes_per_clus; + + if (!cluster) // 起始簇号为0,说明是空文件 + { + // 找一个可用的簇 + cluster = fat32_find_available_cluster(fsbi); + flags = 1; + } + else + { + // 跳转到position所在的簇 + for (uint64_t i = 0; i < clus_offset_in_file; ++i) + cluster = fat32_read_FAT_entry(fsbi, cluster); + } + kdebug("hhhhhhhh"); + // 没有可用的磁盘空间 + if (!cluster) + return -ENOSPC; + + if (flags) // 空文件 + { + finode->first_clus = cluster; + // 写入目录项 + file_ptr->dEntry->dir_inode->sb->sb_ops->write_inode(file_ptr->dEntry->dir_inode); + fat32_write_FAT_entry(fsbi, cluster, 0x0fffffff8); // 写入fat表项 + } + + uint64_t bytes_remain = count; + uint64_t sector; + int64_t retval = 0; + + void *tmp_buffer = kmalloc(fsbi->bytes_per_clus, 0); + kdebug("ggggg"); + do + { + memset(tmp_buffer, 0, fsbi->bytes_per_clus); + sector = fsbi->first_data_sector + (cluster - 2) * fsbi->sec_per_clus; // 计算对应的扇区 + + if (!flags) // 当前簇已分配 + { + // 读取一个簇的数据 + int errno = ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buffer, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); + if (errno != AHCI_SUCCESS) + { + kerror("FAT32 FS(write) read disk error!"); + retval = -EIO; + break; + } + } + + int64_t step_trans_len = 0; // 当前循环传输的字节数 + if (bytes_remain > (fsbi->bytes_per_clus - bytes_offset)) + step_trans_len = (fsbi->bytes_per_clus - bytes_offset); + else + step_trans_len = bytes_remain; + + if (((uint64_t)buf) < USER_MAX_LINEAR_ADDR) + copy_from_user(tmp_buffer + bytes_offset, buf, step_trans_len); + else + memcpy(tmp_buffer + bytes_offset, buf, step_trans_len); + + // 写入数据到对应的簇 + int errno = ahci_operation.transfer(AHCI_CMD_WRITE_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buffer, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); + if (errno != AHCI_SUCCESS) + { + kerror("FAT32 FS(write) read disk error!"); + retval = -EIO; + break; + } + + bytes_remain -= step_trans_len; + buf += step_trans_len; + bytes_offset -= bytes_offset; + + *position += step_trans_len; // 更新文件指针 + kdebug("step_trans_len=%d", step_trans_len); + + int next_clus = 0; + if (bytes_remain) + next_clus = fat32_read_FAT_entry(fsbi, cluster); + else + break; + if (next_clus >= 0x0ffffff8) // 已经到达了最后一个簇,需要分配新簇 + { + next_clus = fat32_find_available_cluster(fsbi); + if (!next_clus) // 没有空闲簇 + { + kfree(tmp_buffer); + return -ENOSPC; + } + // 将簇加入到文件末尾 + fat32_write_FAT_entry(fsbi, cluster, next_clus); + fat32_write_FAT_entry(fsbi, next_clus, 0x0ffffff8); + cluster = next_clus; // 切换当前簇 + flags = 1; // 标记当前簇是新分配的簇 + } + + } while (bytes_remain); + + // 文件大小有增长 + if (*position > (file_ptr->dEntry->dir_inode->file_size)) + { + file_ptr->dEntry->dir_inode->file_size = *position; + file_ptr->dEntry->dir_inode->sb->sb_ops->write_inode(file_ptr->dEntry->dir_inode); + kdebug("new file size=%ld", *position); + } + + kfree(tmp_buffer); + if (!bytes_remain) + retval = count; + kdebug("retval=%lld", retval); + return retval; } // todo: lseek long fat32_lseek(struct vfs_file_t *file_ptr, long offset, long origin) diff --git a/kernel/process/process.c b/kernel/process/process.c index 5f908eab..e36adeec 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -109,34 +109,79 @@ void user_level_function() int fd_num = err_code; int count = 16; - while (count) - { - uchar buf[128] = {0}; - // Test sys_read - addr = (uint64_t)&buf; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - count = err_code; - // 将读取到的数据打印出来 - addr = (ul)buf; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_PUT_STRING), "m"(addr) - : "memory", "r8"); - } + // while (count) + //{ + uchar buf[128] = {0}; + // Test sys_read + addr = (uint64_t)&buf; + __asm__ __volatile__( + "movq %2, %%r8 \n\t" + "movq %3, %%r9 \n\t" + "movq %4, %%r10 \n\t" + "movq %5, %%r11 \n\t" + "movq %6, %%r12 \n\t" + "movq %7, %%r13 \n\t" + "movq %8, %%r14 \n\t" + "movq %9, %%r15 \n\t" + "int $0x80 \n\t" + : "=a"(err_code) + : "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) + : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); + count = err_code; + // 将读取到的数据打印出来 + addr = (ul)buf; + __asm__ __volatile__( + "movq %2, %%r8 \n\t" + "int $0x80 \n\t" + : "=a"(err_code) + : "a"(SYS_PUT_STRING), "m"(addr) + : "memory", "r8"); + // SYS_WRITE + char test1[] = "Test11111111jdjdjdjdjdjd\n"; + + addr = (uint64_t)&test1; + count = 26; + __asm__ __volatile__( + "movq %2, %%r8 \n\t" + "movq %3, %%r9 \n\t" + "movq %4, %%r10 \n\t" + "movq %5, %%r11 \n\t" + "movq %6, %%r12 \n\t" + "movq %7, %%r13 \n\t" + "movq %8, %%r14 \n\t" + "movq %9, %%r15 \n\t" + "int $0x80 \n\t" + : "=a"(err_code) + : "a"(SYS_WRITE), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) + : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); + + // Test sys_read + addr = (uint64_t)&buf; + __asm__ __volatile__( + "movq %2, %%r8 \n\t" + "movq %3, %%r9 \n\t" + "movq %4, %%r10 \n\t" + "movq %5, %%r11 \n\t" + "movq %6, %%r12 \n\t" + "movq %7, %%r13 \n\t" + "movq %8, %%r14 \n\t" + "movq %9, %%r15 \n\t" + "int $0x80 \n\t" + : "=a"(err_code) + : "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) + : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); + count = err_code; + // 将读取到的数据打印出来 + addr = (ul)buf+20; + __asm__ __volatile__( + "movq %2, %%r8 \n\t" + "int $0x80 \n\t" + : "=a"(err_code) + : "a"(SYS_PUT_STRING), "m"(addr) + : "memory", "r8"); + + // Test Sys + //} // Test sys_close __asm__ __volatile__( @@ -152,6 +197,9 @@ void user_level_function() : "=a"(err_code) : "a"(SYS_CLOSE), "m"(fd_num), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); + + while (1) + pause(); } while (1) pause(); diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 94db5375..775f181f 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -46,7 +46,7 @@ void syscall_init() { kinfo("Initializing syscall..."); - set_system_intr_gate(0x80, 0, syscall_int); // 系统调用门 + set_system_trap_gate(0x80, 0, syscall_int); // 系统调用门 } /** @@ -284,7 +284,7 @@ uint64_t sys_write(struct pt_regs *regs) void *buf = (void *)regs->r9; int64_t count = (int64_t)regs->r10; - // kdebug("sys read: fd=%d", fd_num); + kdebug("sys write: fd=%d", fd_num); // 校验文件描述符范围 if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM) @@ -326,5 +326,6 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = [2] = sys_open, [3] = sys_close, [4] = sys_read, - [5 ... 254] = system_call_not_exists, + [5] = sys_write, + [6 ... 254] = system_call_not_exists, [255] = sys_ahci_end_req};