diff --git a/kernel/common/stdio.h b/kernel/common/stdio.h new file mode 100644 index 00000000..c232081b --- /dev/null +++ b/kernel/common/stdio.h @@ -0,0 +1,7 @@ +#pragma once + +#define SEEK_SET 0 /* Seek relative to start-of-file */ +#define SEEK_CUR 1 /* Seek relative to current position */ +#define SEEK_END 2 /* Seek relative to end-of-file */ + +#define SEEK_MAX 3 diff --git a/kernel/driver/disk/ahci/ahci.c b/kernel/driver/disk/ahci/ahci.c index 927f2675..1a67f016 100644 --- a/kernel/driver/disk/ahci/ahci.c +++ b/kernel/driver/disk/ahci/ahci.c @@ -312,7 +312,7 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count, uint64_t buf) { - kdebug("ahci write"); + // kdebug("ahci write"); port->is = 0xffff; // Clear pending interrupt bits int slot = ahci_find_cmdslot(port); if (slot == -1) diff --git a/kernel/filesystem/fat32/fat32.c b/kernel/filesystem/fat32/fat32.c index 5d283111..431310e8 100644 --- a/kernel/filesystem/fat32/fat32.c +++ b/kernel/filesystem/fat32/fat32.c @@ -5,6 +5,7 @@ #include #include #include +#include struct vfs_super_block_operations_t fat32_sb_ops; struct vfs_dir_entry_operations_t fat32_dEntry_ops; @@ -484,8 +485,7 @@ void fat32_write_inode(struct vfs_index_node_t *inode) // 计算目标inode对应数据区的LBA地址 uint64_t fLBA = fsbi->first_data_sector + (finode->dEntry_location_clus - 2) * fsbi->sec_per_clus; - kdebug("fLBA=%d", fLBA); - kdebug("fsbi->first_data_sector=%d", fsbi->first_data_sector); + struct fat32_Directory_t *buf = (struct fat32_Directory_t *)kmalloc(fsbi->bytes_per_clus, 0); memset(buf, 0, fsbi->bytes_per_clus); @@ -495,13 +495,11 @@ void fat32_write_inode(struct vfs_index_node_t *inode) struct fat32_Directory_t *fdEntry = buf + finode->dEntry_location_clus_offset; // 写入fat32文件系统的dir_entry - kdebug("inode->file_size=%#018lx", inode->file_size); - kdebug("before fdEntry->DIR_FileSize=%d", fdEntry->DIR_FileSize); fdEntry->DIR_FileSize = inode->file_size; fdEntry->DIR_FstClusLO = finode->first_clus & 0xffff; fdEntry->DIR_FstClusHI = (finode->first_clus >> 16) | (fdEntry->DIR_FstClusHI & 0xf000); - kdebug("middle fdEntry->DIR_FileSize=%d", fdEntry->DIR_FileSize); + // 将dir entry写回磁盘 ahci_operation.transfer(AHCI_CMD_WRITE_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num); @@ -812,9 +810,43 @@ long fat32_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *po // kdebug("retval=%lld", retval); return retval; } -// todo: lseek -long fat32_lseek(struct vfs_file_t *file_ptr, long offset, long origin) + +/** + * @brief 调整文件的当前访问位置 + * + * @param file_ptr vfs文件指针 + * @param offset 调整的偏移量 + * @param whence 调整方法 + * @return long 更新后的指针位置 + */ +long fat32_lseek(struct vfs_file_t *file_ptr, long offset, long whence) { + struct vfs_index_node_t *inode = file_ptr->dEntry->dir_inode; + + long pos = 0; + switch (whence) + { + case SEEK_SET: // 相对于文件头 + pos = offset; + break; + case SEEK_CUR: // 相对于当前位置 + pos = file_ptr->position + offset; + break; + case SEEK_END: // 相对于文件末尾 + pos = file_ptr->dEntry->dir_inode->file_size + offset; + break; + + default: + return -EINVAL; + break; + } + + if(pos<0||pos>file_ptr->dEntry->dir_inode->file_size) + return -EOVERFLOW; + file_ptr->position = pos; + + kdebug("fat32 lseek -> position=%d", file_ptr->position); + return pos; } // todo: ioctl long fat32_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) diff --git a/kernel/process/process.c b/kernel/process/process.c index ab6efbac..5122aa58 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -8,6 +8,7 @@ #include #include #include +#include extern void system_call(void); extern void kernel_thread_func(void); @@ -142,6 +143,43 @@ void user_level_function() addr = (uint64_t)&test1; count = 19; + __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"); + + addr = 1; + count = SEEK_SET; + fd_num = 0; + // Test lseek + __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_LSEEK), "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"); + + // SYS_WRITE + char test2[] = "K123456789K"; + + addr = (uint64_t)&test2; + count = 11; __asm__ __volatile__( "movq %2, %%r8 \n\t" "movq %3, %%r9 \n\t" diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 775f181f..2128f8f2 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -268,7 +268,6 @@ uint64_t sys_read(struct pt_regs *regs) return ret; } - /** * @brief 向文件写入数据 * @@ -305,6 +304,38 @@ uint64_t sys_write(struct pt_regs *regs) return ret; } +/** + * @brief 调整文件的访问位置 + * + * @param fd_num 文件描述符号 + * @param offset 偏移量 + * @param whence 调整模式 + * @return uint64_t + */ +uint64_t sys_lseek(struct pt_regs *regs) +{ + int fd_num = (int)regs->r8; + long offset = (long)regs->r9; + int whence = (int)regs->r10; + + kdebug("sys_lseek: fd=%d", fd_num); + uint64_t retval = 0; + + // 校验文件描述符范围 + if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM) + return -EBADF; + + // 文件描述符不存在 + if (current_pcb->fds[fd_num] == NULL) + return -EBADF; + + struct vfs_file_t *file_ptr = current_pcb->fds[fd_num]; + if (file_ptr->file_ops && file_ptr->file_ops->lseek) + retval = file_ptr->file_ops->lseek(file_ptr, offset, whence); + + return retval; +} + ul sys_ahci_end_req(struct pt_regs *regs) { ahci_end_request(); @@ -327,5 +358,6 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = [3] = sys_close, [4] = sys_read, [5] = sys_write, - [6 ... 254] = system_call_not_exists, + [6] = sys_lseek, + [7 ... 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 f93ed8f5..a8a2eaeb 100644 --- a/kernel/syscall/syscall_num.h +++ b/kernel/syscall/syscall_num.h @@ -15,5 +15,6 @@ #define SYS_CLOSE 3 #define SYS_READ 4 #define SYS_WRITE 5 +#define SYS_LSEEK 6 #define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用 \ No newline at end of file