mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
parent
ed178b560b
commit
d328bfce6b
3
.gitignore
vendored
3
.gitignore
vendored
@ -11,4 +11,5 @@ serial_opt.txt
|
||||
user/sys_api_lib
|
||||
|
||||
docs/_build
|
||||
draft
|
||||
draft
|
||||
cppcheck.xml
|
18
Makefile
18
Makefile
@ -5,6 +5,16 @@ ifeq ($(EMULATOR), )
|
||||
export EMULATOR=__NO_EMULATION__
|
||||
endif
|
||||
|
||||
# 计算cpu核心数
|
||||
NPROCS:=1
|
||||
OS:=$(shell uname -s)
|
||||
|
||||
ifeq ($(OS),Linux)
|
||||
NPROCS:=$(shell grep -c ^processor /proc/cpuinfo)
|
||||
endif
|
||||
ifeq ($(OS),Darwin) # Assume Mac OS X
|
||||
NPROCS:=$(shell system_profiler | awk '/Number Of CPUs/{print $4}{next;}')
|
||||
endif
|
||||
|
||||
export ARCH=__x86_64__
|
||||
export ROOT_PATH=$(shell pwd)
|
||||
@ -59,5 +69,11 @@ clean:
|
||||
cd .. ;\
|
||||
done
|
||||
|
||||
cppcheck-xml:
|
||||
cppcheck kernel user --platform=unix64 --std=c11 -I user/libs/ -I=kernel/ --force -j $(NPROCS) --xml 2> cppcheck.xml
|
||||
|
||||
cppcheck:
|
||||
cppcheck kernel user --platform=unix64 --std=c11 -I user/libs/ -I=kernel/ --force -j $(NPROCS)
|
||||
|
||||
gdb:
|
||||
gdb -n -x tools/.gdbinit
|
||||
gdb -n -x tools/.gdbinit
|
||||
|
@ -25,4 +25,4 @@ struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc)
|
||||
msi_desc->msg.data = ia64_pci_get_arch_msi_message_data(msi_desc->irq_num, msi_desc->processor, msi_desc->edge_trigger, msi_desc->assert);
|
||||
msi_desc->msg.vector_control = 0;
|
||||
return &(msi_desc->msg);
|
||||
}
|
||||
}
|
||||
|
@ -674,4 +674,5 @@ static long ahci_transfer(struct blk_gendisk *gd, long cmd, uint64_t base_addr,
|
||||
*/
|
||||
static long ahci_ioctl(long cmd, long arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,25 +28,29 @@ static __always_inline struct pci_msix_cap_t __msi_read_msix_cap_list(struct msi
|
||||
cap_list.next_off = (dw0 >> 8) & 0xff;
|
||||
cap_list.msg_ctrl = (dw0 >> 16) & 0xffff;
|
||||
|
||||
cap_list.dword1 = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x4);
|
||||
cap_list.dword2 = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x8);
|
||||
cap_list.dword1 =
|
||||
pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x4);
|
||||
cap_list.dword2 =
|
||||
pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x8);
|
||||
return cap_list;
|
||||
}
|
||||
|
||||
static __always_inline struct pci_msi_cap_t __msi_read_cap_list(struct msi_desc_t *msi_desc, uint32_t cap_off)
|
||||
{
|
||||
struct pci_msi_cap_t cap_list;
|
||||
struct pci_msi_cap_t cap_list = {0};
|
||||
uint32_t dw0;
|
||||
dw0 = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off);
|
||||
cap_list.cap_id = dw0 & 0xff;
|
||||
cap_list.next_off = (dw0 >> 8) & 0xff;
|
||||
cap_list.msg_ctrl = (dw0 >> 16) & 0xffff;
|
||||
|
||||
cap_list.msg_addr_lo = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x4);
|
||||
cap_list.msg_addr_lo =
|
||||
pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x4);
|
||||
uint16_t msg_data_off = 0xc;
|
||||
if (cap_list.msg_ctrl & (1 << 7)) // 64位
|
||||
{
|
||||
cap_list.msg_addr_hi = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x8);
|
||||
cap_list.msg_addr_hi =
|
||||
pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x8);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -54,10 +58,14 @@ static __always_inline struct pci_msi_cap_t __msi_read_cap_list(struct msi_desc_
|
||||
msg_data_off = 0x8;
|
||||
}
|
||||
|
||||
cap_list.msg_data = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + msg_data_off) & 0xffff;
|
||||
cap_list.msg_data = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func,
|
||||
cap_off + msg_data_off) &
|
||||
0xffff;
|
||||
|
||||
cap_list.mask = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x10);
|
||||
cap_list.pending = pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x14);
|
||||
cap_list.mask =
|
||||
pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x10);
|
||||
cap_list.pending =
|
||||
pci_read_config(msi_desc->pci_dev->bus, msi_desc->pci_dev->device, msi_desc->pci_dev->func, cap_off + 0x14);
|
||||
|
||||
return cap_list;
|
||||
}
|
||||
@ -69,7 +77,8 @@ static __always_inline struct pci_msi_cap_t __msi_read_cap_list(struct msi_desc_
|
||||
* @param msix_cap msix capability list的结构体
|
||||
* @return int 错误码
|
||||
*/
|
||||
static __always_inline int __msix_map_table(struct pci_device_structure_header_t *pci_dev, struct pci_msix_cap_t *msix_cap)
|
||||
static __always_inline int __msix_map_table(struct pci_device_structure_header_t *pci_dev,
|
||||
struct pci_msix_cap_t *msix_cap)
|
||||
{
|
||||
// 计算bar寄存器的offset
|
||||
uint32_t bar_off = 0x10 + 4 * (msix_cap->dword1 & 0x7);
|
||||
@ -83,7 +92,8 @@ static __always_inline int __msix_map_table(struct pci_device_structure_header_t
|
||||
mmio_create(pci_dev->msix_mmio_size, VM_IO | VM_DONTCOPY, &pci_dev->msix_mmio_vaddr, &pci_dev->msix_mmio_size);
|
||||
pci_dev->msix_mmio_vaddr &= (~0xf);
|
||||
uint32_t bar = pci_read_config(pci_dev->bus, pci_dev->device, pci_dev->func, bar_off);
|
||||
// kdebug("pci_dev->msix_mmio_vaddr=%#018lx, bar=%#010lx, table offset=%#010lx, table_size=%#010lx, mmio_size=%d", pci_dev->msix_mmio_vaddr, bar, pci_dev->msix_offset, pci_dev->msix_table_size, pci_dev->msix_mmio_size);
|
||||
// kdebug("pci_dev->msix_mmio_vaddr=%#018lx, bar=%#010lx, table offset=%#010lx, table_size=%#010lx, mmio_size=%d",
|
||||
// pci_dev->msix_mmio_vaddr, bar, pci_dev->msix_offset, pci_dev->msix_table_size, pci_dev->msix_mmio_size);
|
||||
|
||||
// 将msix table映射到页表
|
||||
mm_map(&initial_mm, pci_dev->msix_mmio_vaddr, pci_dev->msix_mmio_size, bar);
|
||||
@ -98,7 +108,8 @@ static __always_inline int __msix_map_table(struct pci_device_structure_header_t
|
||||
*/
|
||||
static __always_inline void __msix_set_entry(struct msi_desc_t *msi_desc)
|
||||
{
|
||||
uint64_t *ptr = (uint64_t *)(msi_desc->pci_dev->msix_mmio_vaddr + msi_desc->pci_dev->msix_offset + msi_desc->msi_index * 16);
|
||||
uint64_t *ptr =
|
||||
(uint64_t *)(msi_desc->pci_dev->msix_mmio_vaddr + msi_desc->pci_dev->msix_offset + msi_desc->msi_index * 16);
|
||||
*ptr = ((uint64_t)(msi_desc->msg.address_hi) << 32) | (msi_desc->msg.address_lo);
|
||||
io_mfence();
|
||||
++ptr;
|
||||
@ -177,7 +188,7 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
|
||||
// todo: disable intx
|
||||
// 使能msi-x
|
||||
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
||||
tmp |= (1 << 31);
|
||||
tmp |= (1U << 31);
|
||||
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp);
|
||||
}
|
||||
else
|
||||
@ -191,7 +202,8 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
|
||||
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x4, (uint32_t)(message_addr & 0xffffffff));
|
||||
|
||||
if (message_control & (1 << 7)) // 64位
|
||||
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, (uint32_t)((message_addr >> 32) & 0xffffffff));
|
||||
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8,
|
||||
(uint32_t)((message_addr >> 32) & 0xffffffff));
|
||||
|
||||
// 写入message data
|
||||
|
||||
|
@ -807,7 +807,7 @@ static int xhci_reset_port(const int id, const int port)
|
||||
io_mfence();
|
||||
// 重置当前端口
|
||||
if (XHCI_PORT_IS_USB3(id, port))
|
||||
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 31));
|
||||
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1U << 31));
|
||||
else
|
||||
xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 4));
|
||||
|
||||
@ -825,7 +825,7 @@ static int xhci_reset_port(const int id, const int port)
|
||||
// QEMU对usb的模拟有bug,因此需要检测这里
|
||||
#ifdef __QEMU_EMULATION__
|
||||
|
||||
if (XHCI_PORT_IS_USB3(id, port) && (val & (1 << 31)) == 0)
|
||||
if (XHCI_PORT_IS_USB3(id, port) && (val & (1U << 31)) == 0)
|
||||
break;
|
||||
else if (XHCI_PORT_IS_USB2(id, port) && (val & (1 << 4)) == 0)
|
||||
break;
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
// ========== irq BEGIN ===========
|
||||
|
||||
#define XHCI_IRQ_DONE (1 << 31) // 当command trb 的status的第31位被驱动程序置位时,表明该trb已经执行完成(这是由于xhci规定,第31位可以由驱动程序自行决定用途)
|
||||
#define XHCI_IRQ_DONE (1U << 31) // 当command trb 的status的第31位被驱动程序置位时,表明该trb已经执行完成(这是由于xhci规定,第31位可以由驱动程序自行决定用途)
|
||||
/**
|
||||
* @brief 每个xhci控制器的中断向量号
|
||||
*
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "fat32.h"
|
||||
#include "fat_ent.h"
|
||||
#include <common/errno.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <common/stdio.h>
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
#include <filesystem/MBR.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <mm/slab.h>
|
||||
#include <common/errno.h>
|
||||
#include <common/stdio.h>
|
||||
#include "fat_ent.h"
|
||||
|
||||
struct vfs_super_block_operations_t fat32_sb_ops;
|
||||
struct vfs_dir_entry_operations_t fat32_dEntry_ops;
|
||||
@ -104,7 +104,9 @@ struct vfs_dir_entry_t *fat32_lookup(struct vfs_index_node_t *parent_inode, stru
|
||||
{
|
||||
if (js > dest_dentry->name_length && tmp_ldEntry->LDIR_Name1[x] == 0xffff)
|
||||
continue;
|
||||
else if (js > dest_dentry->name_length || tmp_ldEntry->LDIR_Name1[x] != (uint16_t)(dest_dentry->name[js++])) // 文件名不匹配,检索下一个短目录项
|
||||
else if (js > dest_dentry->name_length ||
|
||||
tmp_ldEntry->LDIR_Name1[x] !=
|
||||
(uint16_t)(dest_dentry->name[js++])) // 文件名不匹配,检索下一个短目录项
|
||||
goto continue_cmp_fail;
|
||||
}
|
||||
|
||||
@ -113,7 +115,9 @@ struct vfs_dir_entry_t *fat32_lookup(struct vfs_index_node_t *parent_inode, stru
|
||||
{
|
||||
if (js > dest_dentry->name_length && tmp_ldEntry->LDIR_Name2[x] == 0xffff)
|
||||
continue;
|
||||
else if (js > dest_dentry->name_length || tmp_ldEntry->LDIR_Name2[x] != (uint16_t)(dest_dentry->name[js++])) // 文件名不匹配,检索下一个短目录项
|
||||
else if (js > dest_dentry->name_length ||
|
||||
tmp_ldEntry->LDIR_Name2[x] !=
|
||||
(uint16_t)(dest_dentry->name[js++])) // 文件名不匹配,检索下一个短目录项
|
||||
goto continue_cmp_fail;
|
||||
}
|
||||
|
||||
@ -122,7 +126,9 @@ struct vfs_dir_entry_t *fat32_lookup(struct vfs_index_node_t *parent_inode, stru
|
||||
{
|
||||
if (js > dest_dentry->name_length && tmp_ldEntry->LDIR_Name3[x] == 0xffff)
|
||||
continue;
|
||||
else if (js > dest_dentry->name_length || tmp_ldEntry->LDIR_Name3[x] != (uint16_t)(dest_dentry->name[js++])) // 文件名不匹配,检索下一个短目录项
|
||||
else if (js > dest_dentry->name_length ||
|
||||
tmp_ldEntry->LDIR_Name3[x] !=
|
||||
(uint16_t)(dest_dentry->name[js++])) // 文件名不匹配,检索下一个短目录项
|
||||
goto continue_cmp_fail;
|
||||
}
|
||||
|
||||
@ -159,7 +165,8 @@ struct vfs_dir_entry_t *fat32_lookup(struct vfs_index_node_t *parent_inode, stru
|
||||
}
|
||||
else // 是文件夹
|
||||
{
|
||||
if (js < dest_dentry->name_length && tmp_dEntry->DIR_Name[x] == dest_dentry->name[js]) // 当前位正确匹配
|
||||
if (js < dest_dentry->name_length &&
|
||||
tmp_dEntry->DIR_Name[x] == dest_dentry->name[js]) // 当前位正确匹配
|
||||
{
|
||||
++js;
|
||||
break; // 进行下一位的匹配
|
||||
@ -284,6 +291,11 @@ struct vfs_dir_entry_t *fat32_lookup(struct vfs_index_node_t *parent_inode, stru
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(unlikely(tmp_dEntry==NULL))
|
||||
{
|
||||
BUG_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
find_lookup_success:; // 找到目标dentry
|
||||
struct vfs_index_node_t *p = vfs_alloc_inode();
|
||||
|
||||
@ -360,13 +372,17 @@ struct vfs_superblock_t *fat32_read_superblock(struct block_device *blk)
|
||||
fsbi->fsinfo_sector_addr_infat = fbs->BPB_FSInfo;
|
||||
fsbi->bootsector_bak_sector_addr_infat = fbs->BPB_BkBootSec;
|
||||
|
||||
printk_color(ORANGE, BLACK, "FAT32 Boot Sector\n\tBPB_FSInfo:%#018lx\n\tBPB_BkBootSec:%#018lx\n\tBPB_TotSec32:%#018lx\n", fbs->BPB_FSInfo, fbs->BPB_BkBootSec, fbs->BPB_TotSec32);
|
||||
printk_color(ORANGE, BLACK,
|
||||
"FAT32 Boot Sector\n\tBPB_FSInfo:%#018lx\n\tBPB_BkBootSec:%#018lx\n\tBPB_TotSec32:%#018lx\n",
|
||||
fbs->BPB_FSInfo, fbs->BPB_BkBootSec, fbs->BPB_TotSec32);
|
||||
|
||||
// fsinfo扇区的信息
|
||||
memset(&fsbi->fsinfo, 0, sizeof(struct fat32_FSInfo_t));
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, blk->bd_start_LBA + fsbi->fsinfo_sector_addr_infat, 1, (uint64_t)&fsbi->fsinfo);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT,
|
||||
blk->bd_start_LBA + fsbi->fsinfo_sector_addr_infat, 1, (uint64_t)&fsbi->fsinfo);
|
||||
|
||||
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
|
||||
sb_ptr->root = vfs_alloc_dentry(2);
|
||||
@ -383,7 +399,8 @@ struct vfs_superblock_t *fat32_read_superblock(struct block_device *blk)
|
||||
sb_ptr->root->dir_inode->file_ops = &fat32_file_ops;
|
||||
sb_ptr->root->dir_inode->file_size = 0;
|
||||
// 计算文件占用的扇区数, 由于最小存储单位是簇,因此需要按照簇的大小来对齐扇区
|
||||
sb_ptr->root->dir_inode->blocks = (sb_ptr->root->dir_inode->file_size + fsbi->bytes_per_clus - 1) / fsbi->bytes_per_sec;
|
||||
sb_ptr->root->dir_inode->blocks =
|
||||
(sb_ptr->root->dir_inode->file_size + fsbi->bytes_per_clus - 1) / fsbi->bytes_per_sec;
|
||||
sb_ptr->root->dir_inode->attribute = VFS_IF_DIR;
|
||||
sb_ptr->root->dir_inode->sb = sb_ptr; // 反向绑定对应的超级块
|
||||
|
||||
@ -449,7 +466,8 @@ void fat32_write_inode(struct vfs_index_node_t *inode)
|
||||
struct fat32_Directory_t *buf = (struct fat32_Directory_t *)kmalloc(fsbi->bytes_per_clus, 0);
|
||||
memset(buf, 0, fsbi->bytes_per_clus);
|
||||
|
||||
inode->sb->blk_device->bd_disk->fops->transfer(inode->sb->blk_device->bd_disk, AHCI_CMD_READ_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf);
|
||||
inode->sb->blk_device->bd_disk->fops->transfer(inode->sb->blk_device->bd_disk, AHCI_CMD_READ_DMA_EXT, fLBA,
|
||||
fsbi->sec_per_clus, (uint64_t)buf);
|
||||
// 计算目标dEntry所在的位置
|
||||
struct fat32_Directory_t *fdEntry = buf + finode->dEntry_location_clus_offset;
|
||||
|
||||
@ -459,44 +477,47 @@ void fat32_write_inode(struct vfs_index_node_t *inode)
|
||||
fdEntry->DIR_FstClusHI = (finode->first_clus >> 16) | (fdEntry->DIR_FstClusHI & 0xf000);
|
||||
|
||||
// 将dir entry写回磁盘
|
||||
inode->sb->blk_device->bd_disk->fops->transfer(inode->sb->blk_device->bd_disk, AHCI_CMD_WRITE_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf);
|
||||
inode->sb->blk_device->bd_disk->fops->transfer(inode->sb->blk_device->bd_disk, AHCI_CMD_WRITE_DMA_EXT, fLBA,
|
||||
fsbi->sec_per_clus, (uint64_t)buf);
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
struct vfs_super_block_operations_t fat32_sb_ops =
|
||||
{
|
||||
.write_superblock = fat32_write_superblock,
|
||||
.put_superblock = fat32_put_superblock,
|
||||
.write_inode = fat32_write_inode,
|
||||
struct vfs_super_block_operations_t fat32_sb_ops = {
|
||||
.write_superblock = fat32_write_superblock,
|
||||
.put_superblock = fat32_put_superblock,
|
||||
.write_inode = fat32_write_inode,
|
||||
};
|
||||
|
||||
// todo: compare
|
||||
long fat32_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// todo: hash
|
||||
long fat32_hash(struct vfs_dir_entry_t *dEntry, char *filename)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// todo: release
|
||||
long fat32_release(struct vfs_dir_entry_t *dEntry)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// todo: iput
|
||||
long fat32_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fat32文件系统对于dEntry的操作
|
||||
*
|
||||
*/
|
||||
struct vfs_dir_entry_operations_t fat32_dEntry_ops =
|
||||
{
|
||||
.compare = fat32_compare,
|
||||
.hash = fat32_hash,
|
||||
.release = fat32_release,
|
||||
.iput = fat32_iput,
|
||||
struct vfs_dir_entry_operations_t fat32_dEntry_ops = {
|
||||
.compare = fat32_compare,
|
||||
.hash = fat32_hash,
|
||||
.release = fat32_release,
|
||||
.iput = fat32_iput,
|
||||
};
|
||||
|
||||
// todo: open
|
||||
@ -529,7 +550,8 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *pos
|
||||
|
||||
// First cluster num of the file
|
||||
uint64_t cluster = finode->first_clus;
|
||||
// kdebug("fsbi->bytes_per_clus=%d fsbi->sec_per_clus=%d finode->first_clus=%d cluster=%d", fsbi->bytes_per_clus, fsbi->sec_per_clus, finode->first_clus, cluster);
|
||||
// kdebug("fsbi->bytes_per_clus=%d fsbi->sec_per_clus=%d finode->first_clus=%d cluster=%d", fsbi->bytes_per_clus,
|
||||
// fsbi->sec_per_clus, finode->first_clus, cluster);
|
||||
|
||||
// kdebug("fsbi->bytes_per_clus=%d", fsbi->bytes_per_clus);
|
||||
|
||||
@ -563,7 +585,8 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *pos
|
||||
uint64_t sector = fsbi->first_data_sector + (cluster - 2) * fsbi->sec_per_clus;
|
||||
|
||||
// 读取一个簇的数据
|
||||
int errno = blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buffer);
|
||||
int errno = blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus,
|
||||
(uint64_t)tmp_buffer);
|
||||
if (errno != AHCI_SUCCESS)
|
||||
{
|
||||
kerror("FAT32 FS(read) error!");
|
||||
@ -656,7 +679,8 @@ long fat32_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *po
|
||||
{
|
||||
// kdebug("read existed sec=%ld", sector);
|
||||
// 读取一个簇的数据
|
||||
int errno = blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buffer);
|
||||
int errno = blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus,
|
||||
(uint64_t)tmp_buffer);
|
||||
if (errno != AHCI_SUCCESS)
|
||||
{
|
||||
// kerror("FAT32 FS(write) read disk error!");
|
||||
@ -678,7 +702,8 @@ long fat32_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *po
|
||||
memcpy(tmp_buffer + bytes_offset, buf, step_trans_len);
|
||||
|
||||
// 写入数据到对应的簇
|
||||
int errno = blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buffer);
|
||||
int errno = blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, sector, fsbi->sec_per_clus,
|
||||
(uint64_t)tmp_buffer);
|
||||
if (errno != AHCI_SUCCESS)
|
||||
{
|
||||
kerror("FAT32 FS(write) write disk error!");
|
||||
@ -767,22 +792,21 @@ long fat32_lseek(struct vfs_file_t *file_ptr, long offset, long whence)
|
||||
}
|
||||
// todo: ioctl
|
||||
long fat32_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg)
|
||||
{
|
||||
{return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fat32文件系统,关于文件的操作
|
||||
*
|
||||
*/
|
||||
struct vfs_file_operations_t fat32_file_ops =
|
||||
{
|
||||
.open = fat32_open,
|
||||
.close = fat32_close,
|
||||
.read = fat32_read,
|
||||
.write = fat32_write,
|
||||
.lseek = fat32_lseek,
|
||||
.ioctl = fat32_ioctl,
|
||||
.readdir = fat32_readdir,
|
||||
struct vfs_file_operations_t fat32_file_ops = {
|
||||
.open = fat32_open,
|
||||
.close = fat32_close,
|
||||
.read = fat32_read,
|
||||
.write = fat32_write,
|
||||
.lseek = fat32_lseek,
|
||||
.ioctl = fat32_ioctl,
|
||||
.readdir = fat32_readdir,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -836,7 +860,8 @@ long fat32_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t
|
||||
uint64_t tmp_dentry_clus_buf_addr = 0;
|
||||
uint64_t tmp_parent_dentry_clus = 0;
|
||||
// 寻找空闲目录项
|
||||
struct fat32_Directory_t *empty_fat32_dentry = fat32_find_empty_dentry(parent_inode, cnt_longname + 1, 0, &tmp_dentry_sector, &tmp_parent_dentry_clus, &tmp_dentry_clus_buf_addr);
|
||||
struct fat32_Directory_t *empty_fat32_dentry = fat32_find_empty_dentry(
|
||||
parent_inode, cnt_longname + 1, 0, &tmp_dentry_sector, &tmp_parent_dentry_clus, &tmp_dentry_clus_buf_addr);
|
||||
// kdebug("found empty dentry, cnt_longname=%ld", cnt_longname);
|
||||
|
||||
finode->first_clus = 0;
|
||||
@ -862,11 +887,13 @@ long fat32_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t
|
||||
|
||||
// kdebug("dest_dEntry->name=%s",dest_dEntry->name);
|
||||
// ======== 填写长目录项
|
||||
fat32_fill_longname(dest_dEntry, (struct fat32_LongDirectory_t *)(empty_fat32_dentry - 1), short_dentry_ChkSum, cnt_longname);
|
||||
fat32_fill_longname(dest_dEntry, (struct fat32_LongDirectory_t *)(empty_fat32_dentry - 1), short_dentry_ChkSum,
|
||||
cnt_longname);
|
||||
|
||||
// ====== 将目录项写回磁盘
|
||||
// kdebug("tmp_dentry_sector=%ld", tmp_dentry_sector);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, tmp_dentry_sector, fsbi->sec_per_clus, tmp_dentry_clus_buf_addr);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, tmp_dentry_sector, fsbi->sec_per_clus,
|
||||
tmp_dentry_clus_buf_addr);
|
||||
|
||||
// 注意:parent字段需要在调用函数的地方进行设置
|
||||
|
||||
@ -916,7 +943,8 @@ int64_t fat32_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_
|
||||
uint64_t tmp_dentry_clus_buf_addr = 0;
|
||||
uint64_t tmp_parent_dentry_clus = 0;
|
||||
// 寻找空闲目录项
|
||||
struct fat32_Directory_t *empty_fat32_dentry = fat32_find_empty_dentry(parent_inode, cnt_longname + 1, 0, &tmp_dentry_sector, &tmp_parent_dentry_clus, &tmp_dentry_clus_buf_addr);
|
||||
struct fat32_Directory_t *empty_fat32_dentry = fat32_find_empty_dentry(
|
||||
parent_inode, cnt_longname + 1, 0, &tmp_dentry_sector, &tmp_parent_dentry_clus, &tmp_dentry_clus_buf_addr);
|
||||
|
||||
// ====== 初始化inode =======
|
||||
struct vfs_index_node_t *inode = vfs_alloc_inode();
|
||||
@ -963,11 +991,13 @@ int64_t fat32_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_
|
||||
uint8_t short_dentry_ChkSum = fat32_ChkSum(empty_fat32_dentry->DIR_Name);
|
||||
|
||||
// ======== 填写长目录项
|
||||
fat32_fill_longname(dEntry, (struct fat32_LongDirectory_t *)(empty_fat32_dentry - 1), short_dentry_ChkSum, cnt_longname);
|
||||
fat32_fill_longname(dEntry, (struct fat32_LongDirectory_t *)(empty_fat32_dentry - 1), short_dentry_ChkSum,
|
||||
cnt_longname);
|
||||
|
||||
// ====== 将目录项写回磁盘
|
||||
// kdebug("tmp_dentry_sector=%ld", tmp_dentry_sector);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, tmp_dentry_sector, fsbi->sec_per_clus, tmp_dentry_clus_buf_addr);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, tmp_dentry_sector, fsbi->sec_per_clus,
|
||||
tmp_dentry_clus_buf_addr);
|
||||
// ====== 初始化新的文件夹的目录项 =====
|
||||
{
|
||||
// kdebug("to create dot and dot dot.");
|
||||
@ -1019,21 +1049,26 @@ fail:;
|
||||
// todo: rmdir
|
||||
int64_t fat32_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// todo: rename
|
||||
int64_t fat32_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry)
|
||||
int64_t fat32_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry,
|
||||
struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// todo: getAttr
|
||||
int64_t fat32_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// todo: setAttr
|
||||
int64_t fat32_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief 读取文件夹(在指定目录中找出有效目录项)
|
||||
@ -1077,7 +1112,8 @@ int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t f
|
||||
uint64_t sector = fsbi->first_data_sector + (cluster - 2) * fsbi->sec_per_clus;
|
||||
// 读取文件夹目录项当前位置起始扇区的数据
|
||||
|
||||
if (AHCI_SUCCESS != blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)buf))
|
||||
if (AHCI_SUCCESS != blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, sector,
|
||||
fsbi->sec_per_clus, (uint64_t)buf))
|
||||
{
|
||||
// 读取失败
|
||||
kerror("Failed to read the file's first sector.");
|
||||
@ -1093,7 +1129,8 @@ int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t f
|
||||
|
||||
name_len = 0;
|
||||
// 逐个查找短目录项
|
||||
for (int i = file_ptr->position % fsbi->bytes_per_clus; i < fsbi->bytes_per_clus; i += 32, file_ptr->position += 32, ++dentry)
|
||||
for (int i = file_ptr->position % fsbi->bytes_per_clus; i < fsbi->bytes_per_clus;
|
||||
i += 32, file_ptr->position += 32, ++dentry)
|
||||
{
|
||||
// 若是长目录项则跳过
|
||||
if (dentry->DIR_Attr == ATTR_LONG_NAME)
|
||||
@ -1107,11 +1144,13 @@ int64_t fat32_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t f
|
||||
long_dentry = (struct fat32_LongDirectory_t *)(dentry - 1);
|
||||
|
||||
// 如果长目录项有效,则读取长目录项
|
||||
if (long_dentry->LDIR_Attr == ATTR_LONG_NAME && long_dentry->LDIR_Ord != 0xe5 && long_dentry->LDIR_Ord != 0x00 && long_dentry->LDIR_Ord != 0x05)
|
||||
if (long_dentry->LDIR_Attr == ATTR_LONG_NAME && long_dentry->LDIR_Ord != 0xe5 &&
|
||||
long_dentry->LDIR_Ord != 0x00 && long_dentry->LDIR_Ord != 0x05)
|
||||
{
|
||||
int count_long_dentry = 0;
|
||||
// 统计长目录项的个数
|
||||
while (long_dentry->LDIR_Attr == ATTR_LONG_NAME && long_dentry->LDIR_Ord != 0xe5 && long_dentry->LDIR_Ord != 0x00 && long_dentry->LDIR_Ord != 0x05)
|
||||
while (long_dentry->LDIR_Attr == ATTR_LONG_NAME && long_dentry->LDIR_Ord != 0xe5 &&
|
||||
long_dentry->LDIR_Ord != 0x00 && long_dentry->LDIR_Ord != 0x05)
|
||||
{
|
||||
++count_long_dentry;
|
||||
if (long_dentry->LDIR_Ord & 0x40) // 最后一个长目录项
|
||||
@ -1224,24 +1263,22 @@ find_dir_success:;
|
||||
return filler(dirent, 0, dir_name, name_len, dentry_type, 0);
|
||||
}
|
||||
|
||||
struct vfs_inode_operations_t fat32_inode_ops =
|
||||
{
|
||||
.create = fat32_create,
|
||||
.mkdir = fat32_mkdir,
|
||||
.rmdir = fat32_rmdir,
|
||||
.lookup = fat32_lookup,
|
||||
.rename = fat32_rename,
|
||||
.getAttr = fat32_getAttr,
|
||||
.setAttr = fat32_setAttr,
|
||||
struct vfs_inode_operations_t fat32_inode_ops = {
|
||||
.create = fat32_create,
|
||||
.mkdir = fat32_mkdir,
|
||||
.rmdir = fat32_rmdir,
|
||||
.lookup = fat32_lookup,
|
||||
.rename = fat32_rename,
|
||||
.getAttr = fat32_getAttr,
|
||||
.setAttr = fat32_setAttr,
|
||||
|
||||
};
|
||||
|
||||
struct vfs_filesystem_type_t fat32_fs_type =
|
||||
{
|
||||
.name = "FAT32",
|
||||
.fs_flags = 0,
|
||||
.read_superblock = fat32_read_superblock,
|
||||
.next = NULL,
|
||||
struct vfs_filesystem_type_t fat32_fs_type = {
|
||||
.name = "FAT32",
|
||||
.fs_flags = 0,
|
||||
.read_superblock = fat32_read_superblock,
|
||||
.next = NULL,
|
||||
};
|
||||
void fat32_init()
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ static int compare(void *a, void *b)
|
||||
static int release(void *value)
|
||||
{
|
||||
// kdebug("release");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ static long ktest_idr_case0(uint64_t arg0, uint64_t arg1)
|
||||
assert(idr_pre_get(&k_idr, 0) == 0);
|
||||
assert(k_idr.id_free_cnt == IDR_FREE_MAX);
|
||||
|
||||
for (int i = 1; i < 64; i++)
|
||||
for (uint64_t i = 1; i < 64; i++)
|
||||
{
|
||||
int id = __lowbit_id(i), chk_id = -1;
|
||||
for (int j = 0; j < 64; j++)
|
||||
|
@ -146,6 +146,7 @@ static long ktest_kfifo_case0_1(uint64_t arg0, uint64_t arg1)
|
||||
kfifo_free_alloc(&fifo);
|
||||
assert(fifo.buffer == NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ktest_case_table kt_kfifo_func_table[] = {
|
||||
|
@ -108,7 +108,8 @@ static int __check_ui_param(const char *name, const uint8_t type, const struct s
|
||||
return -EINVAL;
|
||||
if (ops == NULL)
|
||||
return -EINVAL;
|
||||
if (ops->install == NULL || ops->uninstall == NULL || ops->enable == NULL || ops->disable == NULL || ops->change == NULL)
|
||||
if (ops->install == NULL || ops->uninstall == NULL || ops->enable == NULL || ops->disable == NULL ||
|
||||
ops->change == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -204,6 +205,7 @@ int scm_register(struct scm_ui_framework_t *ui)
|
||||
*/
|
||||
int scm_unregister(struct scm_ui_framework_t *ui)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,6 +216,7 @@ int scm_unregister(struct scm_ui_framework_t *ui)
|
||||
*/
|
||||
int scm_unregister_alloc(struct scm_ui_framework_t *ui)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,19 +256,16 @@ int scm_enable_double_buffer()
|
||||
return -ENOMEM;
|
||||
uart_send_str(COM1, "##to change double buffer##\n");
|
||||
|
||||
if (ptr->ui_ops->change(buf) != 0) // 这里的change回调函数不会是空指针吗 问题2
|
||||
if (ptr->ui_ops->change(buf) != 0) // 这里的change回调函数不会是空指针吗 问题2
|
||||
{
|
||||
|
||||
__destroy_buffer(buf);
|
||||
kfree(buf);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} while (list_next(&ptr->list) != &scm_framework_list); // 枚举链表的每一个ui框架
|
||||
|
||||
|
||||
// 设置定时刷新的对象
|
||||
video_set_refresh_target(__current_framework->buf);
|
||||
// 通知显示驱动,启动双缓冲
|
||||
|
@ -1,12 +1,12 @@
|
||||
//
|
||||
// Created by longjin on 2022/1/22.
|
||||
//
|
||||
#include <common/printk.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/printk.h>
|
||||
|
||||
#include <mm/mm.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <lib/libUI/textui.h>
|
||||
#include <mm/mm.h>
|
||||
|
||||
#include <common/math.h>
|
||||
#include <common/string.h>
|
||||
@ -41,17 +41,19 @@ static int skip_and_atoi(const char **s)
|
||||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串按照fmt和args中的内容进行格式化,然后保存到buf中
|
||||
* @param buf 结果缓冲区
|
||||
* @param fmt 格式化字符串
|
||||
* @param args 内容
|
||||
* @return 最终字符串的长度
|
||||
*/
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
/**
|
||||
* 将字符串按照fmt和args中的内容进行格式化,然后保存到buf中
|
||||
* @param buf 结果缓冲区
|
||||
* @param fmt 格式化字符串
|
||||
* @param args 内容
|
||||
* @return 最终字符串的长度
|
||||
*/
|
||||
// 当需要输出的字符串的指针为空时,使用该字符填充目标字符串的指针
|
||||
static const char __end_zero_char = '\0';
|
||||
|
||||
char *str, *s;
|
||||
char *str = NULL, *s = NULL;
|
||||
|
||||
str = buf;
|
||||
|
||||
@ -150,7 +152,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
precision = va_arg(args, int);
|
||||
++fmt;
|
||||
}
|
||||
else if is_digit (*fmt)
|
||||
else if (is_digit(*fmt))
|
||||
{
|
||||
precision = skip_and_atoi(&fmt);
|
||||
}
|
||||
@ -201,7 +203,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
s = '\0';
|
||||
s = &__end_zero_char;
|
||||
len = strlen(s);
|
||||
if (precision < 0)
|
||||
{
|
||||
@ -475,8 +477,8 @@ static char *write_float_point_num(char *str, double num, int field_width, int p
|
||||
if (sign)
|
||||
--field_width;
|
||||
|
||||
int js_num_z = 0, js_num_d = 0; // 临时数字字符串tmp_num_z tmp_num_d的长度
|
||||
uint64_t num_z = (uint64_t)(num); // 获取整数部分
|
||||
int js_num_z = 0, js_num_d = 0; // 临时数字字符串tmp_num_z tmp_num_d的长度
|
||||
uint64_t num_z = (uint64_t)(num); // 获取整数部分
|
||||
uint64_t num_decimal = (uint64_t)(round(1.0 * (num - num_z) * pow(10, precision))); // 获取小数部分
|
||||
|
||||
if (num == 0 || num_z == 0)
|
||||
|
@ -39,7 +39,8 @@ static __always_inline void __buddy_add_region_obj(int index, struct __mmio_budd
|
||||
static __always_inline struct __mmio_buddy_addr_region *__mmio_buddy_create_region(uint64_t vaddr)
|
||||
{
|
||||
// 申请内存块的空间
|
||||
struct __mmio_buddy_addr_region *region = (struct __mmio_buddy_addr_region *)kzalloc(sizeof(struct __mmio_buddy_addr_region), 0);
|
||||
struct __mmio_buddy_addr_region *region =
|
||||
(struct __mmio_buddy_addr_region *)kzalloc(sizeof(struct __mmio_buddy_addr_region), 0);
|
||||
list_init(®ion->list);
|
||||
region->vaddr = vaddr;
|
||||
return region;
|
||||
@ -67,7 +68,8 @@ static __always_inline void __buddy_split(struct __mmio_buddy_addr_region *regio
|
||||
* @param exp x、y大小的幂
|
||||
* @return int 错误码
|
||||
*/
|
||||
static __always_inline int __buddy_merge_blocks(struct __mmio_buddy_addr_region *x, struct __mmio_buddy_addr_region *y, int exp)
|
||||
static __always_inline int __buddy_merge_blocks(struct __mmio_buddy_addr_region *x, struct __mmio_buddy_addr_region *y,
|
||||
int exp)
|
||||
{
|
||||
// 判断这两个是否是一对伙伴
|
||||
if (unlikely(x->vaddr != buddy_block_vaddr(y->vaddr, exp))) // 不是一对伙伴
|
||||
@ -94,7 +96,8 @@ static __always_inline struct __mmio_buddy_addr_region *__buddy_pop_region(int e
|
||||
{
|
||||
if (unlikely(list_empty(&__mmio_pool.free_regions[__exp2index(exp)].list_head)))
|
||||
return NULL;
|
||||
struct __mmio_buddy_addr_region *r = container_of(list_next(&__mmio_pool.free_regions[__exp2index(exp)].list_head), struct __mmio_buddy_addr_region, list);
|
||||
struct __mmio_buddy_addr_region *r = container_of(list_next(&__mmio_pool.free_regions[__exp2index(exp)].list_head),
|
||||
struct __mmio_buddy_addr_region, list);
|
||||
list_del(&r->list);
|
||||
// 区域计数减1
|
||||
--__mmio_pool.free_regions[__exp2index(exp)].num_free;
|
||||
@ -169,15 +172,20 @@ static void __buddy_merge(int exp)
|
||||
*/
|
||||
struct __mmio_buddy_addr_region *mmio_buddy_query_addr_region(int exp)
|
||||
{
|
||||
if (exp >= MMIO_BUDDY_MAX_EXP)
|
||||
if (unlikely(exp > MMIO_BUDDY_MAX_EXP || exp < MMIO_BUDDY_MIN_EXP))
|
||||
{
|
||||
BUG_ON(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!list_empty(&__mmio_pool.free_regions[__exp2index(exp)].list_head))
|
||||
goto has_block;
|
||||
|
||||
// 若没有符合要求的内存块,则先尝试分裂大的块
|
||||
for (int cur_exp = exp; exp <= MMIO_BUDDY_MAX_EXP; ++cur_exp)
|
||||
for (int cur_exp = exp; cur_exp <= MMIO_BUDDY_MAX_EXP; ++cur_exp)
|
||||
{
|
||||
if (unlikely(list_empty(&__mmio_pool.free_regions[__exp2index(cur_exp)].list_head))) // 一直寻找到有空闲空间的链表
|
||||
if (unlikely(
|
||||
list_empty(&__mmio_pool.free_regions[__exp2index(cur_exp)].list_head))) // 一直寻找到有空闲空间的链表
|
||||
continue;
|
||||
|
||||
// 找到了,逐级向下split
|
||||
|
@ -1,14 +1,13 @@
|
||||
#include "syscall.h"
|
||||
#include <process/process.h>
|
||||
#include <exception/gate.h>
|
||||
#include <exception/irq.h>
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
#include <mm/slab.h>
|
||||
#include <common/errno.h>
|
||||
#include <common/fcntl.h>
|
||||
#include <common/string.h>
|
||||
#include <filesystem/fat32/fat32.h>
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
#include <exception/gate.h>
|
||||
#include <exception/irq.h>
|
||||
#include <filesystem/VFS/VFS.h>
|
||||
#include <filesystem/fat32/fat32.h>
|
||||
#include <mm/slab.h>
|
||||
#include <process/process.h>
|
||||
#include <time/sleep.h>
|
||||
|
||||
@ -36,7 +35,7 @@ ul system_call_not_exists(struct pt_regs *regs)
|
||||
{
|
||||
kerror("System call [ ID #%d ] not exists.", regs->rax);
|
||||
return ESYSCALL_NOT_EXISTS;
|
||||
} // 取消前述宏定义
|
||||
} // 取消前述宏定义
|
||||
|
||||
/**
|
||||
* @brief 重新定义为:把系统调用函数加入系统调用表
|
||||
@ -85,19 +84,19 @@ void syscall_init()
|
||||
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
|
||||
{
|
||||
long err_code;
|
||||
__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"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
__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"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6),
|
||||
"m"(arg7)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
|
||||
return err_code;
|
||||
}
|
||||
@ -122,8 +121,6 @@ ul sys_put_string(struct pt_regs *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief 关闭文件系统调用
|
||||
*
|
||||
@ -170,9 +167,9 @@ uint64_t sys_read(struct pt_regs *regs)
|
||||
int64_t count = (int64_t)regs->r10;
|
||||
|
||||
// 校验buf的空间范围
|
||||
if(SYSCALL_FROM_USER(regs) && (!verify_area((uint64_t)buf, count)))
|
||||
return -EPERM;
|
||||
|
||||
if (SYSCALL_FROM_USER(regs) && (!verify_area((uint64_t)buf, count)))
|
||||
return -EPERM;
|
||||
|
||||
// kdebug("sys read: fd=%d", fd_num);
|
||||
|
||||
// 校验文件描述符范围
|
||||
@ -187,7 +184,7 @@ uint64_t sys_read(struct pt_regs *regs)
|
||||
return -EINVAL;
|
||||
|
||||
struct vfs_file_t *file_ptr = current_pcb->fds[fd_num];
|
||||
uint64_t ret;
|
||||
uint64_t ret = 0;
|
||||
if (file_ptr->file_ops && file_ptr->file_ops->read)
|
||||
ret = file_ptr->file_ops->read(file_ptr, (char *)buf, count, &(file_ptr->position));
|
||||
|
||||
@ -210,8 +207,8 @@ uint64_t sys_write(struct pt_regs *regs)
|
||||
int64_t count = (int64_t)regs->r10;
|
||||
|
||||
// 校验buf的空间范围
|
||||
if(SYSCALL_FROM_USER(regs) && (!verify_area((uint64_t)buf, count)))
|
||||
return -EPERM;
|
||||
if (SYSCALL_FROM_USER(regs) && (!verify_area((uint64_t)buf, count)))
|
||||
return -EPERM;
|
||||
kdebug("sys write: fd=%d", fd_num);
|
||||
|
||||
// 校验文件描述符范围
|
||||
@ -226,7 +223,7 @@ uint64_t sys_write(struct pt_regs *regs)
|
||||
return -EINVAL;
|
||||
|
||||
struct vfs_file_t *file_ptr = current_pcb->fds[fd_num];
|
||||
uint64_t ret;
|
||||
uint64_t ret = 0;
|
||||
if (file_ptr->file_ops && file_ptr->file_ops->write)
|
||||
ret = file_ptr->file_ops->write(file_ptr, (char *)buf, count, &(file_ptr->position));
|
||||
|
||||
@ -287,7 +284,8 @@ uint64_t sys_brk(struct pt_regs *regs)
|
||||
{
|
||||
uint64_t new_brk = PAGE_2M_ALIGN(regs->r8);
|
||||
|
||||
// kdebug("sys_brk input= %#010lx , new_brk= %#010lx bytes current_pcb->mm->brk_start=%#018lx current->end_brk=%#018lx", regs->r8, new_brk, current_pcb->mm->brk_start, current_pcb->mm->brk_end);
|
||||
// kdebug("sys_brk input= %#010lx , new_brk= %#010lx bytes current_pcb->mm->brk_start=%#018lx
|
||||
// current->end_brk=%#018lx", regs->r8, new_brk, current_pcb->mm->brk_start, current_pcb->mm->brk_end);
|
||||
|
||||
if ((int64_t)regs->r8 == -1)
|
||||
{
|
||||
@ -586,30 +584,30 @@ void do_syscall_int(struct pt_regs *regs, unsigned long error_code)
|
||||
regs->rax = ret; // 返回码
|
||||
}
|
||||
|
||||
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
||||
{
|
||||
[0] = system_call_not_exists,
|
||||
[1] = sys_put_string,
|
||||
[2] = sys_open,
|
||||
[3] = sys_close,
|
||||
[4] = sys_read,
|
||||
[5] = sys_write,
|
||||
[6] = sys_lseek,
|
||||
[7] = sys_fork,
|
||||
[8] = sys_vfork,
|
||||
[9] = sys_brk,
|
||||
[10] = sys_sbrk,
|
||||
[11] = sys_reboot,
|
||||
[12] = sys_chdir,
|
||||
[13] = sys_getdents,
|
||||
[14] = sys_execve,
|
||||
[15] = sys_wait4,
|
||||
[16] = sys_exit,
|
||||
[17] = sys_mkdir,
|
||||
[18] = sys_nanosleep,
|
||||
[19] = sys_clock,
|
||||
[20] = sys_pipe,
|
||||
[21] = sys_mstat,
|
||||
[22] = sys_rmdir,
|
||||
[23 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req};
|
||||
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
|
||||
[0] = system_call_not_exists,
|
||||
[1] = sys_put_string,
|
||||
[2] = sys_open,
|
||||
[3] = sys_close,
|
||||
[4] = sys_read,
|
||||
[5] = sys_write,
|
||||
[6] = sys_lseek,
|
||||
[7] = sys_fork,
|
||||
[8] = sys_vfork,
|
||||
[9] = sys_brk,
|
||||
[10] = sys_sbrk,
|
||||
[11] = sys_reboot,
|
||||
[12] = sys_chdir,
|
||||
[13] = sys_getdents,
|
||||
[14] = sys_execve,
|
||||
[15] = sys_wait4,
|
||||
[16] = sys_exit,
|
||||
[17] = sys_mkdir,
|
||||
[18] = sys_nanosleep,
|
||||
[19] = sys_clock,
|
||||
[20] = sys_pipe,
|
||||
[21] = sys_mstat,
|
||||
[22] = sys_rmdir,
|
||||
[23 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req,
|
||||
};
|
||||
|
@ -291,6 +291,7 @@ int shell_cmd_pwd(int argc, char **argv)
|
||||
printf("%s\n", shell_current_path);
|
||||
if (argv != NULL)
|
||||
free(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,6 +328,7 @@ int shell_cmd_cat(int argc, char **argv)
|
||||
free(buf);
|
||||
if (argv != NULL)
|
||||
free(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,6 +361,7 @@ int shell_cmd_touch(int argc, char **argv)
|
||||
close(fd);
|
||||
if (argv != NULL)
|
||||
free(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,7 +372,7 @@ int shell_cmd_touch(int argc, char **argv)
|
||||
* @return int
|
||||
*/
|
||||
// todo:
|
||||
int shell_cmd_rm(int argc, char **argv) {}
|
||||
int shell_cmd_rm(int argc, char **argv) {return 0;}
|
||||
|
||||
/**
|
||||
* @brief 创建文件夹的命令
|
||||
|
@ -16,9 +16,10 @@ int shell_help(int argc, char **argv)
|
||||
printf("Help:\n");
|
||||
for (int i = 0; i < help_table_num; ++i)
|
||||
help_table[i].func();
|
||||
|
||||
if(argc > 1)
|
||||
|
||||
if (argc > 1)
|
||||
free(argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void shell_help_cd()
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "math.h"
|
||||
#include <libc/math.h>
|
||||
#include <libc/stddef.h>
|
||||
|
||||
int64_t pow(int64_t x, int y)
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "printf.h"
|
||||
|
||||
#include <libc/stdio.h>
|
||||
#include <libsystem/syscall.h>
|
||||
#include <libc/string.h>
|
||||
#include <libc/math.h>
|
||||
#include <libc/stdio.h>
|
||||
#include <libc/stdlib.h>
|
||||
#include <libc/string.h>
|
||||
#include <libsystem/syscall.h>
|
||||
|
||||
static char *write_num(char *str, uint64_t num, int base, int field_width, int precision, int flags);
|
||||
static char *write_float_point_num(char *str, double num, int field_width, int precision, int flags);
|
||||
@ -62,17 +62,19 @@ int sprintf(char *buf, const char *fmt, ...)
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串按照fmt和args中的内容进行格式化,然后保存到buf中
|
||||
* @param buf 结果缓冲区
|
||||
* @param fmt 格式化字符串
|
||||
* @param args 内容
|
||||
* @return 最终字符串的长度
|
||||
*/
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
/**
|
||||
* 将字符串按照fmt和args中的内容进行格式化,然后保存到buf中
|
||||
* @param buf 结果缓冲区
|
||||
* @param fmt 格式化字符串
|
||||
* @param args 内容
|
||||
* @return 最终字符串的长度
|
||||
*/
|
||||
// 当需要输出的字符串的指针为空时,使用该字符填充目标字符串的指针
|
||||
static const char __end_zero_char = '\0';
|
||||
|
||||
char *str, *s;
|
||||
char *str = NULL, *s = NULL;
|
||||
|
||||
str = buf;
|
||||
|
||||
@ -222,7 +224,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
s = '\0';
|
||||
s = &__end_zero_char;
|
||||
len = strlen(s);
|
||||
if (precision < 0)
|
||||
{
|
||||
@ -492,9 +494,9 @@ static char *write_float_point_num(char *str, double num, int field_width, int p
|
||||
if (sign)
|
||||
--field_width;
|
||||
|
||||
int js_num_z = 0, js_num_d = 0; // 临时数字字符串tmp_num_z tmp_num_d的长度
|
||||
uint64_t num_z = (uint64_t)(num); // 获取整数部分
|
||||
uint64_t num_decimal = (uint64_t)(round(1.0*(num - num_z) * pow(10, precision))); // 获取小数部分
|
||||
int js_num_z = 0, js_num_d = 0; // 临时数字字符串tmp_num_z tmp_num_d的长度
|
||||
uint64_t num_z = (uint64_t)(num); // 获取整数部分
|
||||
uint64_t num_decimal = (uint64_t)(round(1.0 * (num - num_z) * pow(10, precision))); // 获取小数部分
|
||||
|
||||
if (num == 0 || num_z == 0)
|
||||
tmp_num_z[js_num_z++] = '0';
|
||||
|
Loading…
x
Reference in New Issue
Block a user