mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 12:16:31 +00:00
实现了打开、关闭、读取文件的功能
This commit is contained in:
@ -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);
|
||||
@ -359,6 +360,7 @@ static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_
|
||||
// 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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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];
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <filesystem/MBR.h>
|
||||
#include <process/spinlock.h>
|
||||
#include <mm/slab.h>
|
||||
#include <common/errno.h>
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -85,9 +85,10 @@ void user_level_function()
|
||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||
: "memory", "r8");
|
||||
*/
|
||||
|
||||
while (1)
|
||||
{
|
||||
// 测试sys_open
|
||||
char string[] = "/xx/12.png";
|
||||
char string[] = "a.txt";
|
||||
long err_code = 1;
|
||||
int zero = 0;
|
||||
uint64_t addr = (ul)string;
|
||||
@ -105,6 +106,53 @@ void user_level_function()
|
||||
: "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);
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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的系统调用
|
Reference in New Issue
Block a user