mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 10:06: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->fis_type = FIS_TYPE_REG_H2D;
|
||||||
cmdfis->c = 1; // Command
|
cmdfis->c = 1; // Command
|
||||||
cmdfis->command = ATA_CMD_READ_DMA_EXT;
|
cmdfis->command = AHCI_CMD_READ_DMA_EXT;
|
||||||
|
|
||||||
cmdfis->lba0 = (uint8_t)startl;
|
cmdfis->lba0 = (uint8_t)startl;
|
||||||
cmdfis->lba1 = (uint8_t)(startl >> 8);
|
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;
|
cmdfis->counth = (count >> 8) & 0xFF;
|
||||||
|
|
||||||
// The below loop waits until the port is no longer busy before issuing a new command
|
// 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++;
|
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
|
port->ci = 1 << slot; // Issue command
|
||||||
|
|
||||||
|
current_pcb->flags |= PROC_NEED_SCHED;
|
||||||
sched_cfs();
|
sched_cfs();
|
||||||
int retval = AHCI_SUCCESS;
|
int retval = AHCI_SUCCESS;
|
||||||
// Wait for completion
|
// 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);
|
FIS_REG_H2D *cmdfis = (FIS_REG_H2D *)(&cmdtbl->cfis);
|
||||||
cmdfis->fis_type = FIS_TYPE_REG_H2D;
|
cmdfis->fis_type = FIS_TYPE_REG_H2D;
|
||||||
cmdfis->c = 1; // Command
|
cmdfis->c = 1; // Command
|
||||||
cmdfis->command = ATA_CMD_WRITE_DMA_EXT;
|
cmdfis->command = AHCI_CMD_WRITE_DMA_EXT;
|
||||||
cmdfis->lba0 = (uint8_t)startl;
|
cmdfis->lba0 = (uint8_t)startl;
|
||||||
cmdfis->lba1 = (uint8_t)(startl >> 8);
|
cmdfis->lba1 = (uint8_t)(startl >> 8);
|
||||||
cmdfis->lba2 = (uint8_t)(startl >> 16);
|
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);
|
// printk("[slot]{%d}", slot);
|
||||||
port->ci = 1; // Issue command
|
port->ci = 1; // Issue command
|
||||||
|
|
||||||
|
current_pcb->flags |= PROC_NEED_SCHED;
|
||||||
sched_cfs();
|
sched_cfs();
|
||||||
int retval = AHCI_SUCCESS;
|
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为空
|
// 由于ahci不需要中断即可读取磁盘,因此end handler为空
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case ATA_CMD_READ_DMA_EXT:
|
case AHCI_CMD_READ_DMA_EXT:
|
||||||
pack->blk_pak.end_handler = NULL;
|
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;
|
break;
|
||||||
case ATA_CMD_WRITE_DMA_EXT:
|
case AHCI_CMD_WRITE_DMA_EXT:
|
||||||
pack->blk_pak.end_handler = NULL;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
pack->blk_pak.end_handler = NULL;
|
pack->blk_pak.end_handler = NULL;
|
||||||
@ -485,10 +487,10 @@ static long ahci_query_disk()
|
|||||||
|
|
||||||
switch (pack->blk_pak.cmd)
|
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);
|
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;
|
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);
|
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;
|
break;
|
||||||
default:
|
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;
|
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);
|
pack = ahci_make_request(cmd, base_addr, count, buf, ahci_ctrl_num, port_num);
|
||||||
ahci_submit(pack);
|
ahci_submit(pack);
|
||||||
|
@ -17,11 +17,11 @@
|
|||||||
#define HBA_PxCMD_FR 0x4000
|
#define HBA_PxCMD_FR 0x4000
|
||||||
#define HBA_PxCMD_CR 0x8000
|
#define HBA_PxCMD_CR 0x8000
|
||||||
|
|
||||||
#define ATA_DEV_BUSY 0x80
|
#define AHCI_DEV_BUSY 0x80
|
||||||
#define ATA_DEV_DRQ 0x08
|
#define AHCI_DEV_DRQ 0x08
|
||||||
|
|
||||||
#define ATA_CMD_READ_DMA_EXT 0x25
|
#define AHCI_CMD_READ_DMA_EXT 0x25
|
||||||
#define ATA_CMD_WRITE_DMA_EXT 0x30
|
#define AHCI_CMD_WRITE_DMA_EXT 0x30
|
||||||
|
|
||||||
#define HBA_PxIS_TFES (1 << 30) /* TFES - Task File Error Status */
|
#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];
|
unsigned char buf[512];
|
||||||
memset(buf, 0, 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;
|
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];
|
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 (*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 (*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 (*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 buf_size, 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 (*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);
|
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 <filesystem/MBR.h>
|
||||||
#include <process/spinlock.h>
|
#include <process/spinlock.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
|
#include <common/errno.h>
|
||||||
|
|
||||||
struct vfs_super_block_operations_t fat32_sb_ops;
|
struct vfs_super_block_operations_t fat32_sb_ops;
|
||||||
struct vfs_dir_entry_operations_t fat32_dEntry_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};
|
uint8_t buf[512] = {0};
|
||||||
|
|
||||||
// 读取文件系统的boot扇区
|
// 读取文件系统的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
|
// 挂载文件系统到vfs
|
||||||
return vfs_mount_fs("FAT32", (void *)(&DPT->DPTE[part_num]), VFS_DPT_MBR, buf, ahci_ctrl_num, ahci_port_num, part_num);
|
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表项数
|
||||||
// FAT每项4bytes
|
// 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];
|
uint32_t buf[256];
|
||||||
memset(buf, 0, fsbi->bootsector.BPB_BytesPerSec);
|
memset(buf, 0, fsbi->bytes_per_sec);
|
||||||
|
|
||||||
// 读取一个sector的数据,
|
// 读取一个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);
|
(uint64_t)&buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num);
|
||||||
|
|
||||||
// 返回下一个fat表项的值(也就是下一个cluster)
|
// 返回下一个fat表项的值(也就是下一个cluster)
|
||||||
return buf[cluster & (fat_ent_per_sec - 1)] & 0x0fffffff;
|
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];
|
uint32_t buf[256];
|
||||||
memset(buf, 0, fsbi->bootsector.BPB_BytesPerSec);
|
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);
|
(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);
|
buf[cluster & (fat_ent_per_sec - 1)] = (buf[cluster & (fat_ent_per_sec - 1)] & 0xf0000000) | (value & 0x0fffffff);
|
||||||
// 向FAT1和FAT2写入数据
|
// 向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);
|
(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);
|
(uint64_t)&buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num);
|
||||||
|
|
||||||
return 0;
|
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);
|
// 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(AHCI_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, 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;
|
tmp_dEntry = (struct fat32_Directory_t *)buf;
|
||||||
|
|
||||||
@ -344,7 +345,6 @@ find_lookup_success:; // 找到目标dentry
|
|||||||
return dest_dentry;
|
return dest_dentry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建fat32文件系统的超级块
|
* @brief 创建fat32文件系统的超级块
|
||||||
*
|
*
|
||||||
@ -396,7 +396,7 @@ struct vfs_superblock_t *fat32_read_superblock(void *DPTE, uint8_t DPT_type, voi
|
|||||||
|
|
||||||
// fsinfo扇区的信息
|
// fsinfo扇区的信息
|
||||||
memset(&fsbi->fsinfo, 0, sizeof(struct fat32_FSInfo_t));
|
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);
|
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
|
// 初始化超级块的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);
|
uint8_t *buf = (uint8_t *)kmalloc(fsbi->bytes_per_clus, 0);
|
||||||
memset(buf, 0, sizeof(fsbi->bytes_per_clus));
|
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所在的位置
|
// 计算目标dEntry所在的位置
|
||||||
struct fat32_Directory_t *fdEntry = (struct fat32_Directory_t *)((uint64_t)buf + finode->dEntry_location_clus_offset);
|
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);
|
fdEntry->DIR_FstClusHI = (finode->first_clus >> 16) | (fdEntry->DIR_FstClusHI & 0xf000);
|
||||||
|
|
||||||
// 将dir entry写回磁盘
|
// 将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);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
@ -546,14 +546,95 @@ long fat32_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
|||||||
// todo: close
|
// todo: close
|
||||||
long fat32_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
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
|
// 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
|
// todo: lseek
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// 内核层的起始地址
|
// 内核层的起始地址
|
||||||
#define PAGE_OFFSET (0xffff800000000000UL)
|
#define PAGE_OFFSET (0xffff800000000000UL)
|
||||||
#define KERNEL_BASE_LINEAR_ADDR (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_4K_SHIFT 12
|
||||||
#define PAGE_2M_SHIFT 21
|
#define PAGE_2M_SHIFT 21
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
#include"../common/asm.h"
|
#include"../common/asm.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 导出内核线程的执行引导程序
|
||||||
|
* 目的是还原执行现场(在kernel_thread中伪造的)
|
||||||
|
* 执行到这里时,rsp位于栈顶,然后弹出寄存器值
|
||||||
|
* 弹出之后还要向上移动7个unsigned long的大小,从而弹出额外的信息(详见pt_regs)
|
||||||
|
*/
|
||||||
|
|
||||||
ENTRY(kernel_thread_func)
|
ENTRY(kernel_thread_func)
|
||||||
popq %r15
|
popq %r15
|
||||||
popq %r14
|
popq %r14
|
||||||
|
@ -85,9 +85,10 @@ void user_level_function()
|
|||||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||||
: "memory", "r8");
|
: "memory", "r8");
|
||||||
*/
|
*/
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
// 测试sys_open
|
// 测试sys_open
|
||||||
char string[] = "/xx/12.png";
|
char string[] = "a.txt";
|
||||||
long err_code = 1;
|
long err_code = 1;
|
||||||
int zero = 0;
|
int zero = 0;
|
||||||
uint64_t addr = (ul)string;
|
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)
|
: "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");
|
: "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)
|
while (1)
|
||||||
pause();
|
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 初始化内核进程
|
* @brief 初始化内核进程
|
||||||
*
|
*
|
||||||
@ -302,15 +310,6 @@ void process_init()
|
|||||||
|
|
||||||
initial_mm.stack_start = _stack_start;
|
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
|
// 初始化进程和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);
|
// 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;
|
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));
|
memset(file_ptr, 0, sizeof(struct vfs_file_t));
|
||||||
|
|
||||||
int errcode = -1;
|
int errcode = -1;
|
||||||
@ -202,6 +202,66 @@ uint64_t sys_open(struct pt_regs *regs)
|
|||||||
return fd_num;
|
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)
|
ul sys_ahci_end_req(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ahci_end_request();
|
ahci_end_request();
|
||||||
@ -221,5 +281,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
|||||||
[0] = system_call_not_exists,
|
[0] = system_call_not_exists,
|
||||||
[1] = sys_put_string,
|
[1] = sys_put_string,
|
||||||
[2] = sys_open,
|
[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};
|
[255] = sys_ahci_end_req};
|
||||||
|
@ -12,5 +12,7 @@
|
|||||||
#define SYS_NOT_EXISTS 0
|
#define SYS_NOT_EXISTS 0
|
||||||
#define SYS_PUT_STRING 1
|
#define SYS_PUT_STRING 1
|
||||||
#define SYS_OPEN 2
|
#define SYS_OPEN 2
|
||||||
|
#define SYS_CLOSE 3
|
||||||
|
#define SYS_READ 4
|
||||||
|
|
||||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
Reference in New Issue
Block a user