From b3ad8405a421557df63266d319ad53ae92d14f16 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Wed, 27 Apr 2022 20:49:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86=E6=89=93=E5=BC=80?= =?UTF-8?q?=E3=80=81=E5=85=B3=E9=97=AD=E3=80=81=E8=AF=BB=E5=8F=96=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/driver/disk/ahci/ahci.c | 24 +++--- kernel/driver/disk/ahci/ahci.h | 8 +- kernel/filesystem/MBR.c | 2 +- kernel/filesystem/VFS/VFS.h | 4 +- kernel/filesystem/fat32/fat32.c | 115 +++++++++++++++++++++++---- kernel/mm/mm.h | 2 +- kernel/process/proc.S | 7 ++ kernel/process/process.c | 133 ++++++++++++++++---------------- kernel/syscall/syscall.c | 66 +++++++++++++++- kernel/syscall/syscall_num.h | 2 + 10 files changed, 258 insertions(+), 105 deletions(-) diff --git a/kernel/driver/disk/ahci/ahci.c b/kernel/driver/disk/ahci/ahci.c index eb1e436e..bfee93fc 100644 --- a/kernel/driver/disk/ahci/ahci.c +++ b/kernel/driver/disk/ahci/ahci.c @@ -254,7 +254,7 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t cmdfis->fis_type = FIS_TYPE_REG_H2D; cmdfis->c = 1; // Command - cmdfis->command = ATA_CMD_READ_DMA_EXT; + cmdfis->command = AHCI_CMD_READ_DMA_EXT; cmdfis->lba0 = (uint8_t)startl; cmdfis->lba1 = (uint8_t)(startl >> 8); @@ -269,7 +269,7 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t cmdfis->counth = (count >> 8) & 0xFF; // The below loop waits until the port is no longer busy before issuing a new command - while ((port->tfd & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && spin < 1000000) + while ((port->tfd & (AHCI_DEV_BUSY | AHCI_DEV_DRQ)) && spin < 1000000) { spin++; } @@ -281,6 +281,7 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t port->ci = 1 << slot; // Issue command + current_pcb->flags |= PROC_NEED_SCHED; sched_cfs(); int retval = AHCI_SUCCESS; // Wait for completion @@ -344,7 +345,7 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_ FIS_REG_H2D *cmdfis = (FIS_REG_H2D *)(&cmdtbl->cfis); cmdfis->fis_type = FIS_TYPE_REG_H2D; cmdfis->c = 1; // Command - cmdfis->command = ATA_CMD_WRITE_DMA_EXT; + cmdfis->command = AHCI_CMD_WRITE_DMA_EXT; cmdfis->lba0 = (uint8_t)startl; cmdfis->lba1 = (uint8_t)(startl >> 8); cmdfis->lba2 = (uint8_t)(startl >> 16); @@ -358,7 +359,8 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_ cmdfis->counth = count >> 8; // printk("[slot]{%d}", slot); port->ci = 1; // Issue command - + + current_pcb->flags |= PROC_NEED_SCHED; sched_cfs(); int retval = AHCI_SUCCESS; @@ -432,13 +434,13 @@ static struct ahci_request_packet_t *ahci_make_request(long cmd, uint64_t base_a // 由于ahci不需要中断即可读取磁盘,因此end handler为空 switch (cmd) { - case ATA_CMD_READ_DMA_EXT: + case AHCI_CMD_READ_DMA_EXT: pack->blk_pak.end_handler = NULL; - pack->blk_pak.cmd = ATA_CMD_READ_DMA_EXT; + pack->blk_pak.cmd = AHCI_CMD_READ_DMA_EXT; break; - case ATA_CMD_WRITE_DMA_EXT: + case AHCI_CMD_WRITE_DMA_EXT: pack->blk_pak.end_handler = NULL; - pack->blk_pak.cmd = ATA_CMD_WRITE_DMA_EXT; + pack->blk_pak.cmd = AHCI_CMD_WRITE_DMA_EXT; break; default: pack->blk_pak.end_handler = NULL; @@ -485,10 +487,10 @@ static long ahci_query_disk() switch (pack->blk_pak.cmd) { - case ATA_CMD_READ_DMA_EXT: + case AHCI_CMD_READ_DMA_EXT: ret_val = ahci_read(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->blk_pak.LBA_start & 0xFFFFFFFF, ((pack->blk_pak.LBA_start) >> 32) & 0xFFFFFFFF, pack->blk_pak.count, pack->blk_pak.buffer_vaddr); break; - case ATA_CMD_WRITE_DMA_EXT: + case AHCI_CMD_WRITE_DMA_EXT: ret_val = ahci_write(&(ahci_devices[pack->ahci_ctrl_num].hba_mem->ports[pack->port_num]), pack->blk_pak.LBA_start & 0xFFFFFFFF, ((pack->blk_pak.LBA_start) >> 32) & 0xFFFFFFFF, pack->blk_pak.count, pack->blk_pak.buffer_vaddr); break; default: @@ -530,7 +532,7 @@ static long ahci_transfer(long cmd, uint64_t base_addr, uint64_t count, uint64_t { struct ahci_request_packet_t *pack = NULL; - if (cmd == ATA_CMD_READ_DMA_EXT || cmd == ATA_CMD_WRITE_DMA_EXT) + if (cmd == AHCI_CMD_READ_DMA_EXT || cmd == AHCI_CMD_WRITE_DMA_EXT) { pack = ahci_make_request(cmd, base_addr, count, buf, ahci_ctrl_num, port_num); ahci_submit(pack); diff --git a/kernel/driver/disk/ahci/ahci.h b/kernel/driver/disk/ahci/ahci.h index 3cedb6d0..ef807651 100644 --- a/kernel/driver/disk/ahci/ahci.h +++ b/kernel/driver/disk/ahci/ahci.h @@ -17,11 +17,11 @@ #define HBA_PxCMD_FR 0x4000 #define HBA_PxCMD_CR 0x8000 -#define ATA_DEV_BUSY 0x80 -#define ATA_DEV_DRQ 0x08 +#define AHCI_DEV_BUSY 0x80 +#define AHCI_DEV_DRQ 0x08 -#define ATA_CMD_READ_DMA_EXT 0x25 -#define ATA_CMD_WRITE_DMA_EXT 0x30 +#define AHCI_CMD_READ_DMA_EXT 0x25 +#define AHCI_CMD_WRITE_DMA_EXT 0x30 #define HBA_PxIS_TFES (1 << 30) /* TFES - Task File Error Status */ diff --git a/kernel/filesystem/MBR.c b/kernel/filesystem/MBR.c index bfaad4ee..dcb2296b 100644 --- a/kernel/filesystem/MBR.c +++ b/kernel/filesystem/MBR.c @@ -14,7 +14,7 @@ struct MBR_disk_partition_table_t *MBR_read_partition_table(uint8_t ahci_ctrl_nu { unsigned char buf[512]; memset(buf, 0, 512); - ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, 0, 1, (uint64_t)&buf, ahci_ctrl_num, ahci_port_num); + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, 0, 1, (uint64_t)&buf, ahci_ctrl_num, ahci_port_num); MBR_partition_tables[ahci_ctrl_num][ahci_port_num] = *(struct MBR_disk_partition_table_t *)buf; return &MBR_partition_tables[ahci_ctrl_num][ahci_port_num]; } \ No newline at end of file diff --git a/kernel/filesystem/VFS/VFS.h b/kernel/filesystem/VFS/VFS.h index e7ec1707..bc37000b 100644 --- a/kernel/filesystem/VFS/VFS.h +++ b/kernel/filesystem/VFS/VFS.h @@ -127,8 +127,8 @@ struct vfs_file_operations_t { long (*open)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr); long (*close)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr); - long (*read)(struct vfs_file_t *file_ptr, char *buf, uint64_t buf_size, long *position); - long (*write)(struct vfs_file_t *file_ptr, char *buf, uint64_t buf_size, long *position); + long (*read)(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *position); + long (*write)(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *position); long (*lseek)(struct vfs_file_t *file_ptr, long offset, long origin); long (*ioctl)(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg); }; diff --git a/kernel/filesystem/fat32/fat32.c b/kernel/filesystem/fat32/fat32.c index 10b23442..8241c237 100644 --- a/kernel/filesystem/fat32/fat32.c +++ b/kernel/filesystem/fat32/fat32.c @@ -4,6 +4,7 @@ #include #include #include +#include struct vfs_super_block_operations_t fat32_sb_ops; struct vfs_dir_entry_operations_t fat32_dEntry_ops; @@ -30,7 +31,7 @@ struct vfs_superblock_t *fat32_register_partition(uint8_t ahci_ctrl_num, uint8_t uint8_t buf[512] = {0}; // 读取文件系统的boot扇区 - ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, DPT->DPTE[part_num].starting_LBA, 1, (uint64_t)&buf, ahci_ctrl_num, ahci_port_num); + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, DPT->DPTE[part_num].starting_LBA, 1, (uint64_t)&buf, ahci_ctrl_num, ahci_port_num); // 挂载文件系统到vfs return vfs_mount_fs("FAT32", (void *)(&DPT->DPTE[part_num]), VFS_DPT_MBR, buf, ahci_ctrl_num, ahci_port_num, part_num); @@ -47,17 +48,17 @@ uint32_t fat32_read_FAT_entry(fat32_sb_info_t *fsbi, uint32_t cluster) { // 计算每个扇区内含有的FAT表项数 // FAT每项4bytes - uint32_t fat_ent_per_sec = (fsbi->bootsector.BPB_BytesPerSec >> 2); // 该值应为2的n次幂 + uint32_t fat_ent_per_sec = (fsbi->bytes_per_sec >> 2); // 该值应为2的n次幂 + uint32_t buf[256]; - memset(buf, 0, fsbi->bootsector.BPB_BytesPerSec); + memset(buf, 0, fsbi->bytes_per_sec); // 读取一个sector的数据, - ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); // 返回下一个fat表项的值(也就是下一个cluster) return buf[cluster & (fat_ent_per_sec - 1)] & 0x0fffffff; - ; } /** @@ -76,14 +77,14 @@ uint32_t fat32_write_FAT_entry(fat32_sb_info_t *fsbi, uint32_t cluster, uint32_t uint32_t buf[256]; memset(buf, 0, fsbi->bootsector.BPB_BytesPerSec); - ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); buf[cluster & (fat_ent_per_sec - 1)] = (buf[cluster & (fat_ent_per_sec - 1)] & 0xf0000000) | (value & 0x0fffffff); // 向FAT1和FAT2写入数据 - ahci_operation.transfer(ATA_CMD_WRITE_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, + ahci_operation.transfer(AHCI_CMD_WRITE_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); - ahci_operation.transfer(ATA_CMD_WRITE_DMA_EXT, fsbi->FAT2_base_sector + (cluster / fat_ent_per_sec), 1, + ahci_operation.transfer(AHCI_CMD_WRITE_DMA_EXT, fsbi->FAT2_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); return 0; @@ -120,8 +121,8 @@ struct vfs_dir_entry_t *fat32_lookup(struct vfs_index_node_t *parent_inode, stru // kdebug("sector=%d",sector); // 读取父目录项的起始簇数据 - ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); - // ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, sector, fat32_part_info[part_id].bootsector.BPB_SecPerClus, (uint64_t)buf, fat32_part_info[part_id].ahci_ctrl_num, fat32_part_info[part_id].ahci_port_num); + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); + // ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, sector, fat32_part_info[part_id].bootsector.BPB_SecPerClus, (uint64_t)buf, fat32_part_info[part_id].ahci_ctrl_num, fat32_part_info[part_id].ahci_port_num); tmp_dEntry = (struct fat32_Directory_t *)buf; @@ -344,7 +345,6 @@ find_lookup_success:; // 找到目标dentry return dest_dentry; } - /** * @brief 创建fat32文件系统的超级块 * @@ -396,7 +396,7 @@ struct vfs_superblock_t *fat32_read_superblock(void *DPTE, uint8_t DPT_type, voi // fsinfo扇区的信息 memset(&fsbi->fsinfo, 0, sizeof(struct fat32_FSInfo_t)); - ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, MBR_DPTE->starting_LBA + fbs->BPB_FSInfo, 1, (uint64_t)&fsbi->fsinfo, ahci_ctrl_num, ahci_port_num); + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, MBR_DPTE->starting_LBA + fbs->BPB_FSInfo, 1, (uint64_t)&fsbi->fsinfo, ahci_ctrl_num, ahci_port_num); printk_color(BLUE, BLACK, "FAT32 FSInfo\n\tFSI_LeadSig:%#018lx\n\tFSI_StrucSig:%#018lx\n\tFSI_Free_Count:%#018lx\n", fsbi->fsinfo.FSI_LeadSig, fsbi->fsinfo.FSI_StrucSig, fsbi->fsinfo.FSI_Free_Count); // 初始化超级块的dir entry @@ -485,7 +485,7 @@ void fat32_write_inode(struct vfs_index_node_t *inode) uint8_t *buf = (uint8_t *)kmalloc(fsbi->bytes_per_clus, 0); memset(buf, 0, sizeof(fsbi->bytes_per_clus)); - ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); + ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); // 计算目标dEntry所在的位置 struct fat32_Directory_t *fdEntry = (struct fat32_Directory_t *)((uint64_t)buf + finode->dEntry_location_clus_offset); @@ -496,7 +496,7 @@ void fat32_write_inode(struct vfs_index_node_t *inode) fdEntry->DIR_FstClusHI = (finode->first_clus >> 16) | (fdEntry->DIR_FstClusHI & 0xf000); // 将dir entry写回磁盘 - ahci_operation.transfer(ATA_CMD_WRITE_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); + ahci_operation.transfer(AHCI_CMD_WRITE_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); kfree(buf); } @@ -546,14 +546,95 @@ long fat32_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) // todo: close long fat32_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) { + return VFS_SUCCESS; } -// todo: read -long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t buf_size, long *position) +/** + * @brief 从fat32文件系统读取数据 + * + * @param file_ptr 文件描述符 + * @param buf 输出缓冲区 + * @param count 要读取的字节数 + * @param position 文件指针位置 + * @return long 执行成功:传输的字节数量 执行失败:错误码(小于0) + */ +long fat32_read(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; + + // 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; + // bytes offset in clus + uint64_t bytes_offset = (*position) % fsbi->bytes_per_clus; + + if (!cluster) + return -EFAULT; + + // find the actual cluster on disk of the specified position + for (int i = 0; i < total_clus_of_file; ++i) + cluster = fat32_read_FAT_entry(fsbi, cluster); + + // 如果需要读取的数据边界大于文件大小 + if (*position + count > file_ptr->dEntry->dir_inode->file_size) + count = file_ptr->dEntry->dir_inode->file_size - *position; + + // 剩余还需要传输的字节数量 + uint64_t bytes_remain = count; + + // alloc buffer memory space for ahci transfer + void *tmp_buffer = kmalloc(fsbi->bytes_per_clus, 0); + + int64_t retval = 0; + do + { + + memset(tmp_buffer, 0, fsbi->bytes_per_clus); + uint64_t sector = fsbi->first_data_sector + (cluster - 2) * fsbi->sec_per_clus; + // 读取一个簇的数据 + 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(read) 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_to_user(buf, tmp_buffer + bytes_offset, step_trans_len); + else + memcpy(buf, tmp_buffer, step_trans_len); + + bytes_remain -= step_trans_len; + buf += step_trans_len; + bytes_offset -= bytes_offset; + + *position += step_trans_len; // 更新文件指针 + + cluster = fat32_read_FAT_entry(fsbi, cluster); + } while (bytes_remain && (cluster < 0x0ffffff8) && cluster != 0); + + kfree(tmp_buffer); + + if(!bytes_remain) + retval = count; + + return retval; } // todo: write -long fat32_write(struct vfs_file_t *file_ptr, char *buf, uint64_t buf_size, long *position) +long fat32_write(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *position) { } // todo: lseek diff --git a/kernel/mm/mm.h b/kernel/mm/mm.h index 50a9e57c..a4b4d569 100644 --- a/kernel/mm/mm.h +++ b/kernel/mm/mm.h @@ -9,7 +9,7 @@ // 内核层的起始地址 #define PAGE_OFFSET (0xffff800000000000UL) #define KERNEL_BASE_LINEAR_ADDR (0xffff800000000000UL) -#define USER_MAX_LINEAR_ADDR 0x00007fffffffffffUL; +#define USER_MAX_LINEAR_ADDR 0x00007fffffffffffUL #define PAGE_4K_SHIFT 12 #define PAGE_2M_SHIFT 21 diff --git a/kernel/process/proc.S b/kernel/process/proc.S index 63c4aff3..afb7f9c7 100644 --- a/kernel/process/proc.S +++ b/kernel/process/proc.S @@ -1,5 +1,12 @@ #include"../common/asm.h" +/** + * @brief 导出内核线程的执行引导程序 + * 目的是还原执行现场(在kernel_thread中伪造的) + * 执行到这里时,rsp位于栈顶,然后弹出寄存器值 + * 弹出之后还要向上移动7个unsigned long的大小,从而弹出额外的信息(详见pt_regs) + */ + ENTRY(kernel_thread_func) popq %r15 popq %r14 diff --git a/kernel/process/process.c b/kernel/process/process.c index 2482303f..5f908eab 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -85,26 +85,74 @@ void user_level_function() : "a"(SYS_PUT_STRING), "m"(addr) : "memory", "r8"); */ + while (1) + { + // 测试sys_open + char string[] = "a.txt"; + long err_code = 1; + int zero = 0; + uint64_t addr = (ul)string; + __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_OPEN), "m"(addr), "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"); - // 测试sys_open - char string[] = "/xx/12.png"; - long err_code = 1; - int zero = 0; - uint64_t addr = (ul)string; - __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_OPEN), "m"(addr), "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"); + 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"); + } + + // Test sys_close + __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_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(); } @@ -204,46 +252,6 @@ ul process_thread_do_exit(ul code) ; } -/** - * @brief 导出内核线程的执行引导程序 - * 目的是还原执行现场(在kernel_thread中伪造的) - * 执行到这里时,rsp位于栈顶,然后弹出寄存器值 - * 弹出之后还要向上移动7个unsigned long的大小,从而弹出额外的信息(详见pt_regs) - */ -/* -void kernel_thread_func(void) -{ - __asm__ volatile( - //"kernel_thread_func: \n\t" - " popq %r15 \n\t" - " popq %r14 \n\t" - " popq %r13 \n\t" - " popq %r12 \n\t" - " popq %r11 \n\t" - " popq %r10 \n\t" - " popq %r9 \n\t" - " popq %r8 \n\t" - " popq %rbx \n\t" - " popq %rcx \n\t" - " popq %rdx \n\t" - " popq %rsi \n\t" - " popq %rdi \n\t" - " popq %rbp \n\t" - " popq %rax \n\t" - " movq %rax, %ds \n\t" - " popq %rax \n\t" - " movq %rax, %es \n\t" - " popq %rax \n\t" - " addq $0x38, %rsp \n\t" - ///////////////////////////////// - " movq %rdx, %rdi \n\t" - " callq *%rbx \n\t" - " movq %rax, %rdi \n\t" - " callq process_thread_do_exit \n\t"); -} - -*/ - /** * @brief 初始化内核进程 * @@ -302,15 +310,6 @@ void process_init() initial_mm.stack_start = _stack_start; - /* - // 向MSR寄存器组中的 IA32_SYSENTER_CS寄存器写入内核的代码段的地址 - wrmsr(0x174, KERNEL_CS); - // 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp(在syscall入口中会将rsp减去相应的数值) - wrmsr(0x175, current_pcb->thread->rbp); - - // 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。 - wrmsr(0x176, (ul)system_call); - */ // 初始化进程和tss // set_tss64((uint *)phys_2_virt(TSS64_Table), initial_thread.rbp, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7); diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 26eb9de9..754792b6 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -148,7 +148,7 @@ uint64_t sys_open(struct pt_regs *regs) return -EISDIR; // 创建文件描述符 - struct vfs_file_t *file_ptr = (struct vfs_f2ile_t *)kmalloc(sizeof(struct vfs_file_t), 0); + struct vfs_file_t *file_ptr = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0); memset(file_ptr, 0, sizeof(struct vfs_file_t)); int errcode = -1; @@ -202,6 +202,66 @@ uint64_t sys_open(struct pt_regs *regs) return fd_num; } +/** + * @brief 关闭文件系统调用 + * + * @param fd_num 文件描述符号 + * + * @param regs + * @return uint64_t + */ +uint64_t sys_close(struct pt_regs *regs) +{ + int fd_num = (int)regs->r8; + + kdebug("sys close: fd=%d", fd_num); + // 校验文件描述符范围 + if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM) + return -EBADF; + + struct vfs_file_t *file_ptr = current_pcb->fds[fd_num]; + uint64_t ret; + // If there is a valid close function + if (file_ptr->file_ops && file_ptr->file_ops->close) + ret = file_ptr->file_ops->close(file_ptr->dEntry->dir_inode, file_ptr); + + kfree(file_ptr); + current_pcb->fds[fd_num] = NULL; + return 0; +} + +/** + * @brief 从文件中读取数据 + * + * @param fd_num regs->r8 文件描述符号 + * @param buf regs->r9 输出缓冲区 + * @param count regs->r10 要读取的字节数 + * + * @return uint64_t + */ +uint64_t sys_read(struct pt_regs *regs) +{ + int fd_num = (int)regs->r8; + void *buf = (void*)regs->r9; + int64_t count = (int64_t)regs->r10; + + // kdebug("sys read: fd=%d", fd_num); + + // 校验文件描述符范围 + if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM) + return -EBADF; + + if (count < 0) + return -EINVAL; + + struct vfs_file_t *file_ptr = current_pcb->fds[fd_num]; + uint64_t ret; + if (file_ptr->file_ops && file_ptr->file_ops->read) + ret = file_ptr->file_ops->read(file_ptr, (char *)buf, count, &(file_ptr->position)); + + return ret; +} + ul sys_ahci_end_req(struct pt_regs *regs) { ahci_end_request(); @@ -221,5 +281,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = [0] = system_call_not_exists, [1] = sys_put_string, [2] = sys_open, - [3 ... 254] = system_call_not_exists, + [3] = sys_close, + [4] = sys_read, + [5 ... 254] = system_call_not_exists, [255] = sys_ahci_end_req}; diff --git a/kernel/syscall/syscall_num.h b/kernel/syscall/syscall_num.h index f035e8cf..cb79334d 100644 --- a/kernel/syscall/syscall_num.h +++ b/kernel/syscall/syscall_num.h @@ -12,5 +12,7 @@ #define SYS_NOT_EXISTS 0 #define SYS_PUT_STRING 1 #define SYS_OPEN 2 +#define SYS_CLOSE 3 +#define SYS_READ 4 #define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用 \ No newline at end of file