bugfix: 修正潜在的错误路径 (#64)

* bugfix: 修正潜在的错误路径

* 修正格式
This commit is contained in:
login 2022-10-22 20:17:40 +08:00 committed by GitHub
parent ed178b560b
commit d328bfce6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 269 additions and 188 deletions

3
.gitignore vendored
View File

@ -11,4 +11,5 @@ serial_opt.txt
user/sys_api_lib
docs/_build
draft
draft
cppcheck.xml

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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控制器的中断向量号
*

View File

@ -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()
{

View File

@ -25,6 +25,7 @@ static int compare(void *a, void *b)
static int release(void *value)
{
// kdebug("release");
return 0;
}
/**

View File

@ -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++)

View File

@ -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[] = {

View File

@ -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);
// 通知显示驱动,启动双缓冲

View File

@ -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)

View File

@ -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(&region->list);
region->vaddr = vaddr;
return region;
@ -67,7 +68,8 @@ static __always_inline void __buddy_split(struct __mmio_buddy_addr_region *regio
* @param exp xy大小的幂
* @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

View File

@ -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,
};

View File

@ -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

View File

@ -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()

View File

@ -1,4 +1,4 @@
#include "math.h"
#include <libc/math.h>
#include <libc/stddef.h>
int64_t pow(int64_t x, int y)

View File

@ -1,5 +1,3 @@
#include "libm.h"
#if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1

View File

@ -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';