diff --git a/docs/community/ChangeLog/V0.1.x/V0.1.8.md b/docs/community/ChangeLog/V0.1.x/V0.1.8.md new file mode 100644 index 000000000..3d970da3b --- /dev/null +++ b/docs/community/ChangeLog/V0.1.x/V0.1.8.md @@ -0,0 +1,556 @@ +# V0.1.8 + +:::{note} +本文作者:龙进 + + +2023年8月16日 +::: + +## 贡献者名单 + +DragonOS V0.1.8版本由以下小伙伴贡献代码: + +- 龙进 +- 侯嘉滢 +- 吴宇健 +- 黄厅 +- 孔维超 +- 蔡嘉鑫 +- 池克俭 +- zhaoyao73 +- 周瀚杰 +- Bullet <93781792+GP-Bullet@users.noreply.github.com> +- 櫻井桃華 <89176634+TihayaKousaka@users.noreply.github.com> +- Tptogiar <2528891112@qq.com> + +## 赞助者名单 + +感谢以下同学的赞赏,我们将不断努力! + +- 万晓兰 +- David Wen +- [Seele.Clover](https://github.com/seeleclover) +- [FindWangHao](https://github.com/FindWangHao) +- [ferchiel](https://github.com/ferchiel) +- 叶锦毅 +- 林 +- Albert +- [TerryLeeSCUT · GitHub](https://github.com/TerryLeeSCUT) +- slientbard +- 悟 +- 匿名热心人士 + +## 更新内容-内核 + +### 新特性 + +- refactor: 重构系统调用模块 (#267) +- feature: 添加AlignBox和int_like宏 (#272) +- refactor: 新的ipi功能&kick_cpu功能的重写 (#274) +- feature: 实现gettimeofday()系统调用和clocksource+timekeeping子模块 (#278) +- refactor: PCI设备中断重构,并删去USB相关代码 (#285) +- feature: 注册串口设备,创建字符设备框架(#290) +- refactor: 新的内存管理模块 (#303) +- feature: 新的二进制加载器、elf解析器 (#303) +- feature: 增加 ListenTable 来检测端口占用 (#291) +- feature: 替换 local_irq_save 为 IrqFlagsGuard 实现 (#317) +- feature: 实现系统调用Fstat (#295) +- feature: 实现内核通知链 notifier chain (#316) +- feature: 增加fcntl系统调用 (#323) +- feature: 添加per cpu变量支持 (#327) +- feature: spinlock守卫新增leak,spinlock新增force unlock功能.(#329) + +### bugfix +- bugfix: 修复无法正常读取stdin的问题 (#264) +- bugfix: 修复了当传入ahci驱动的缓冲区地址为用户缓冲区时,产生的内存越界问题.(采用分配内核缓冲区的方式临时解决) (#265) +- bugfix: 解决由于local_irq_save、local_irq_restore函数的汇编不规范导致影响栈行为的bug。 (#303) +- bugfix: 解决local_irq_save未关中断的错误 (#303) +- bugfix: 解决arch_try_cmpxchg对于指针处理的错误 (#307) +- bugfix: 修复了wait4的异常报错 (#312) +- bugfix: 修正null设备以及zero设备无法open、行为不符合预期的问题 (#314) +- bugfix: 修正fat文件系统未能正确的扩展文件大小的bug (#323) +- bugfix: 修正rwlock有的地方由于未使用ManuallyDrop导致的use after free问题 (#329) + + +## 更新内容-用户环境 + +### 新特性 +- feature: 新增http server (#265) + +### bugfix +- bugfix: 解决链接时,由于crt*.o未按照升序排列导致init段链接错误的问题 (#265) + + +## 更新内容-其他 + +- bugfix: 固定编译工具链、修复由于新版rust编译器问题导致的报错。 (#258) +- feature: Makefile: 根目录下添加make help命令 (#271) +- doc: 更新github issue模板 (#277) +- bugfix: 解决relibc的头文件没能识别__dragonos__定义的问题 (#315) +- feature: 设置内核、relibc的远程为dragonos的git镜像站,防止国内网络问题导致编译失败 (#318) +- feature: 自动安装、更新dadk (#319) + +## 更新内容-软件移植 + +- feature: 移植了sqlite3 (#323) + +## 源码、发布版镜像下载 + +  您可以通过以下方式获得源代码: + +### 通过Git获取 + +- 您可以访问[https://github.com/DragonOS-Community/DragonOS/releases](https://github.com/DragonOS-Community/DragonOS/releases)下载发布版的代码,以及编译好的,可运行的磁盘镜像。 +- 我们在gitee上也有镜像仓库可供下载:[https://gitee.com/DragonOS/DragonOS](https://gitee.com/DragonOS/DragonOS) + +### 通过DragonOS软件镜像站获取 + +  为解决国内访问GitHub慢、不稳定的问题,同时为了方便开发者们下载DragonOS的每个版本的代码,我们特意搭建了镜像站,您可以通过以下地址访问镜像站: + +  您可以通过镜像站获取到DragonOS的代码压缩包,以及编译好的可运行的磁盘镜像。 + +- [https://mirrors.DragonOS.org](https://mirrors.DragonOS.org) +- [https://git.mirrors.DragonOS.org](https://git.mirrors.DragonOS.org) +- 国内镜像加速: [https://mirrors.ringotek.cn/](https://mirrors.ringotek.cn/) + +## 开放源代码声明 + + +:::{note} +为促进DragonOS项目的健康发展,DragonOS以GPLv2开源协议进行发布。所有能获得到DragonOS源代码以及相应的软件制品(包括但不限于二进制副本、文档)的人,都能享有我们通过GPLv2协议授予您的权利,同时您也需要遵守协议中规定的义务。 + +这是一个相当严格的,保护开源软件健康发展,不被侵占的协议。 + +对于大部分的善意的人们而言,您不会违反我们的开源协议。 + +我们鼓励DragonOS的自由传播、推广,但是请确保所有行为没有侵犯他人的合法权益,也没有违反GPLv2协议。 + +请特别注意,对于违反开源协议的,尤其是**商业闭源使用以及任何剽窃、学术不端行为将会受到严肃的追责**。(这是最容易违反我们的开源协议的场景)。 + +并且,请注意,按照GPLv2协议的要求,基于DragonOS修改或二次开发的软件,必须同样采用GPLv2协议开源,并标明其基于DragonOS进行了修改。亦需保证这些修改版本的用户能方便的获取到DragonOS的原始版本。 + +您必须使得DragonOS的开发者们,能够以同样的方式,从公开渠道获取到您二次开发的版本的源代码,否则您将违反GPLv2协议。 + +关于协议详细内容,还敬请您请阅读项目根目录下的**LICENSE**文件。请注意,按照GPLv2协议的要求,**只有英文原版才具有法律效力**。任何翻译版本都仅供参考。 +::: + +### 开源软件使用情况 + +  DragonOS在开发的过程中,参考了一些开源项目的设计,或者引入了他们的部分代码,亦或是受到了他们的启发。现将他们列在下面。我们对这些开源项目的贡献者们致以最衷心的感谢! + +格式:<项目名> - <链接> - <开源协议> + +- Linux - https://git.kernel.org/ - GPLv2 +- skiftOS - https://github.com/skiftOS/skift - MIT +- FYSOS - https://github.com/fysnet/FYSOS - [FYSOS' License](https://github.com/fysnet/FYSOS/blob/9a8968e3d6600de34539c028c843f4c06d134039/license.txt) +- LemonOS - https://github.com/LemonOSProject/LemonOS.git - BSD 2-Clause License +- LZ4 - https://github.com/lz4/lz4 - BSD 2-Clause license +- SerenityOS - https://github.com/SerenityOS/serenity.git - BSD 2-Clause license +- MINE - 《一个64位操作系统的设计与实现》田宇; 人民邮电出版社 +- chcore - 《现代操作系统:设计与实现》陈海波,夏虞斌; 机械工业出版社 +- SimpleKernel - https://github.com/Simple-XX/SimpleKernel - MIT +- rcore-fs - https://github.com/rcore-os/rcore-fs.git - MIT +- redox - https://gitlab.redox-os.org/redox-os/redox - MIT + +## 当前版本的所有提交记录 + +```text +commit 40176b1c6603d487b7eb66fb81e641f0932ab90a +Author: longjin +Date: Tue Aug 15 15:06:57 2023 +0000 + + 删除无用代码,并把about app的版本号更新为0.1.8 + +commit 67b481888770c6469f572f244a4f97e42da77d1f +Author: houmkh <1119644616@qq.com> +Date: Mon Aug 14 12:18:46 2023 +0800 + + 移动fstat (#330) + + * 移动fstat + +commit 90a0a49048fdaf5e31320d0c87f8bed8db1bd882 +Author: LoGin +Date: Mon Aug 14 01:24:49 2023 +0800 + + 修正rwlock有的地方由于未使用ManuallyDrop导致的use after free && spinlock守卫新增leak,spinlock新增force unlock功能.(#329) + + 1.修正rwlock有的地方由于未使用ManuallyDrop导致的use after free + 2. spinlock守卫新增leak,spinlock新增force unlock功能. + +commit c3dad0011d331d782670e14723aa48e98fbac787 +Author: LoGin +Date: Sun Aug 13 16:28:24 2023 +0800 + + 添加per cpu变量支持 (#327) + +commit 42c97fa7f4fee7eeefeda5d2b7ed14f598a58493 +Author: LoGin +Date: Tue Aug 8 23:45:04 2023 +0800 + + 删除旧的libELF (#324) + +commit 6d81180b3b7328466b976b69c5f7782aa66d8a89 +Author: LoGin +Date: Tue Aug 8 23:39:22 2023 +0800 + + 移植sqlite3,并修复一些bug (#323) + + * bugfix: 程序加载器映射内存时,计算要映射的大小不正确的问题。 + + * 修正brk系统调用不符合规范的地方 + + * bugfix: 修正fat文件系统未能正确的扩展文件大小的bug + + * 增加fcntl系统调用 + + * 移植sqlite3 + +commit 26887c6334cdca2d13ad71dec27fb69faa0a57be +Author: LoGin +Date: Mon Aug 7 01:38:52 2023 +0800 + + bugfix: 解决取消低地址映射时,错误的把重映射的物理页释放,从而导致的use after free问题。 (#321) + +commit 729a96ef47f473d535d8317a2ace5ba141fd282a +Author: Xshine +Date: Sun Aug 6 12:53:47 2023 +0800 + + 实现内核通知链 notifier chain (#316) + + * 实现通知链块结构 + + * 实现通知链的基本功能 + + * 实现 atomic notifier chain + + * 实现 blocking notifier chain + + * 使用 rust 范式完成功能 + + * 支持回调次数 nr_to_call + + * 移动至 libs 目录 + + * 完善通知链相关方法 + + * 修正相关格式 + + * 文档编写 + + * 更改文档路径 + +commit be63f3b2b6b472daa3ee17180aa607409cb9d182 +Author: houmkh <1119644616@qq.com> +Date: Sat Aug 5 18:52:46 2023 +0800 + + 实现系统调用Fstat (#295) + + * fstat + + * 修改syscall.rs中的verify_area + +commit 9550910ae1de900e0291a84d268e8873fa142902 +Author: Chiichen <39649411+Chiichen@users.noreply.github.com> +Date: Sat Aug 5 18:30:55 2023 +0800 + + 替换 local_irq_save 为 IrqFlagsGuard 实现 (#317) + +commit abf3f634bf7e13e829556e962e7c73a85d163335 +Author: LoGin +Date: Sat Aug 5 15:30:06 2023 +0800 + + 自动安装、更新dadk (#319) + + * auto install/auto update dadk + +commit d6fd9c1e8025dd679339f9156477cb7d26d3db0d +Author: LoGin +Date: Sat Aug 5 15:04:08 2023 +0800 + + 设置内核、relibc的远程为dragonos的git镜像站,防止国内网络问题导致编译失败 (#318) + +commit 1a62e7767c1215f9668915b42de770e7993711bf +Author: LoGin +Date: Wed Aug 2 18:11:05 2023 +0800 + + 解决relibc的头文件没能识别__dragonos__定义的问题 (#315) + +commit 06500303303ec14711b4f995e2058e12703f0f2c +Author: LoGin +Date: Wed Aug 2 17:33:16 2023 +0800 + + 修正null设备以及zero设备无法open、行为不符合预期的问题 (#314) + +commit 4da3758acf0327d429dfce3d313b50c2e0fc7723 +Author: Chiichen <39649411+Chiichen@users.noreply.github.com> +Date: Wed Aug 2 14:29:59 2023 +0800 + + 修复了wait4的异常报错 (#312) + + * 修复了wait4的异常报错 + +commit 821bb9a2dcfd28f9878d53ba722bdf164cf00f69 +Author: Xshine +Date: Fri Jul 28 17:51:05 2023 +0800 + + 增加 ListenTable 来检测端口占用 (#291) + + * 增加 ListenTable 来检测端口占用 + + + * 使用Arc封装GlobalSocketHandle + + * 删除 listen 处的端口检测逻辑,延至实现端口复用时完成 + + * 设立两张表,分别记录TCP和UDP的端口占用 + + * 实现 meatadata 相关逻辑 + + * 实现socket关闭时,端口在表中移除 + + * 使用端口管理器重构端口记录表 + + * 修正与RawSocket相关的端口管理逻辑 + + * 补充测试文件 + + * 修正 unbind_port 在逻辑错误 + + * 修正格式问题 + + --------- + + Co-authored-by: longjin + +commit 7cc4a02c7ff7bafd798b185beb7b0c2986b9f32f +Author: zhaoyao73 +Date: Fri Jul 28 03:44:45 2023 -0400 + + fix arch_try_cmpxchg macro declaration (#307) + + fix arch_try_cmpxchg in atomic_cmpxchg + + Co-authored-by: Yao Zhao + +commit a30434f5201ca4c60b9515c8c23444fea3b5a8c6 +Author: zhaoyao73 +Date: Tue Jul 25 10:02:42 2023 -0400 + + fix some script bugs (#304) + + add arch linux prerequisited packages + + Co-authored-by: Yao Zhao + +commit 40fe15e0953f989ccfeb74826d61621d43dea6bb +Author: LoGin +Date: Sat Jul 22 16:27:02 2023 +0800 + + 新的内存管理模块 (#303) + +   实现了具有优秀架构设计的新的内存管理模块,对内核空间和用户空间的内存映射、分配、释放、管理等操作进行了封装,使得内核开发者可以更加方便地进行内存管理。 + +   内存管理模块主要由以下类型的组件组成: + + - **硬件抽象层(MemoryManagementArch)** - 提供对具体处理器架构的抽象,使得内存管理模块可以在不同的处理器架构上运行 + - **页面映射器(PageMapper)**- 提供对虚拟地址和物理地址的映射,以及页表的创建、填写、销毁、权限管理等操作。分为两种类型:内核页表映射器(KernelMapper)和用户页表映射器(位于具体的用户地址空间结构中) + - **页面刷新器(PageFlusher)** - 提供对页表的刷新操作(整表刷新、单页刷新、跨核心刷新) + - **页帧分配器(FrameAllocator)** - 提供对页帧的分配、释放、管理等操作。具体来说,包括BumpAllocator、BuddyAllocator + - **小对象分配器** - 提供对小内存对象的分配、释放、管理等操作。指的是内核里面的SlabAllocator (SlabAllocator的实现目前还没有完成) + - **MMIO空间管理器** - 提供对MMIO地址空间的分配、管理操作。(目前这个模块待进一步重构) + - **用户地址空间管理机制** - 提供对用户地址空间的管理。 + - VMA机制 - 提供对用户地址空间的管理,包括VMA的创建、销毁、权限管理等操作 + - 用户映射管理 - 与VMA机制共同作用,管理用户地址空间的映射 + - **系统调用层** - 提供对用户空间的内存管理系统调用,包括mmap、munmap、mprotect、mremap等 + - **C接口兼容层** - 提供对原有的C代码的接口,是的C代码能够正常运行。 + + + 除上面的新增内容以外,其它的更改内容: + - 新增二进制加载器,以及elf的解析器 + - 解决由于local_irq_save、local_irq_restore函数的汇编不规范导致影响栈行为的bug。 + - 解决local_irq_save未关中断的错误。 + - 修复sys_gettimeofday对timezone参数的处理的bug + + --------- + + Co-authored-by: kong + +commit bb5f098a864cee36b7d2c1ab9c029c0280d94a8a +Author: LoGin +Date: Sat Jul 22 16:24:55 2023 +0800 + + Revert "新的内存管理模块 (#301)" (#302) + + This reverts commit d8ad0a5e7724469abd5cc3cf271993538878033e. + +commit d8ad0a5e7724469abd5cc3cf271993538878033e +Author: LoGin +Date: Sat Jul 22 16:22:17 2023 +0800 + + 新的内存管理模块 (#301) + +   实现了具有优秀架构设计的新的内存管理模块,对内核空间和用户空间的内存映射、分配、释放、管理等操作进行了封装,使得内核开发者可以更加方便地进行内存管理。 + +   内存管理模块主要由以下类型的组件组成: + + - **硬件抽象层(MemoryManagementArch)** - 提供对具体处理器架构的抽象,使得内存管理模块可以在不同的处理器架构上运行 + - **页面映射器(PageMapper)**- 提供对虚拟地址和物理地址的映射,以及页表的创建、填写、销毁、权限管理等操作。分为两种类型:内核页表映射器(KernelMapper)和用户页表映射器(位于具体的用户地址空间结构中) + - **页面刷新器(PageFlusher)** - 提供对页表的刷新操作(整表刷新、单页刷新、跨核心刷新) + - **页帧分配器(FrameAllocator)** - 提供对页帧的分配、释放、管理等操作。具体来说,包括BumpAllocator、BuddyAllocator + - **小对象分配器** - 提供对小内存对象的分配、释放、管理等操作。指的是内核里面的SlabAllocator (SlabAllocator的实现目前还没有完成) + - **MMIO空间管理器** - 提供对MMIO地址空间的分配、管理操作。(目前这个模块待进一步重构) + - **用户地址空间管理机制** - 提供对用户地址空间的管理。 + - VMA机制 - 提供对用户地址空间的管理,包括VMA的创建、销毁、权限管理等操作 + - 用户映射管理 - 与VMA机制共同作用,管理用户地址空间的映射 + - **系统调用层** - 提供对用户空间的内存管理系统调用,包括mmap、munmap、mprotect、mremap等 + - **C接口兼容层** - 提供对原有的C代码的接口,是的C代码能够正常运行。 + + + 除上面的新增内容以外,其它的更改内容: + - 新增二进制加载器,以及elf的解析器 + - 解决由于local_irq_save、local_irq_restore函数的汇编不规范导致影响栈行为的bug。 + - 解决local_irq_save未关中断的错误。 + - 修复sys_gettimeofday对timezone参数的处理的bug + +commit 0663027b111ffb6ff93becd60ffef1e2b8fbd4c6 +Author: TingHuang <92705854+TingSHub@users.noreply.github.com> +Date: Wed Jul 12 12:49:45 2023 +0800 + + 注册串口设备,创建字符设备框架(#290) + + * 按照rust规范修改两个函数名称 + + * 修改一些函数句柄以符合rust规范 + + * 添加字符设备相关 + + * 添加字符设备相关文件 + + * 添加字符设备驱动框架代码 + + * 将串口注册 + + * 规范代码 + +commit cc36cf4a186be834e6c2ab857b9b9501ddb8b1eb +Author: YJwu2023 +Date: Sat Jul 8 17:22:42 2023 +0800 + + PCI设备中断重构,删去USB相关代码 (#285) + + * 修复ecam无法获取MCFG table的问题 + + * 完善pcie + + * 完善irq的错误检测机制 + +commit 2311e2f30048d09250afc3e2e4e7029627996655 +Author: 櫻井桃華 <89176634+TihayaKousaka@users.noreply.github.com> +Date: Fri Jul 7 22:50:46 2023 +0800 + + 修改makefile通过编译 (#287) + +commit 36fd013004ee0bd5fc7cfb452ba22531a83a859c +Author: houmkh <1119644616@qq.com> +Date: Sat Jun 17 22:48:15 2023 +0800 + + 实现gettimeofday()系统调用和clocksource+timekeeping子模块 (#278) + + - 实现gettimeofday()系统调用 + - 实现clocksource+timekeeping子模块部分功能 + - 实现了timespec转换成日期时间 + +commit a55ac7b928a6ca08483bbb3355bea55f1446ccab +Author: LoGin +Date: Tue Jun 6 17:44:54 2023 +0800 + + Update issue templates (#277) + +commit 5f57834372f6cb720ba14103effa4799e195a963 +Author: Tptogiar <2528891112@qq.com> +Date: Tue Jun 6 16:41:02 2023 +0800 + + Makefile: 根目录下添加make help命令 (#271) + + * Makefile: 根目录下添加make help命令 + + * Makefile: 补充根目录Makefile的help命令 + +commit aa0367d69e15989684109c5b454e85da9ecb1975 +Author: LoGin +Date: Tue May 30 10:21:11 2023 +0800 + + 新的ipi功能&kick_cpu功能的重写 (#274) + +commit bb24249faabc5006784aa98ca17b4cbdcb788c65 +Author: LoGin +Date: Sun May 28 23:00:37 2023 +0800 + + 添加AlignBox和int_like宏 (#272) + +commit ab5c8ca46db8e7d4793a9791292122b0b9684274 +Author: login +Date: Wed May 24 17:05:33 2023 +0800 + + 重构系统调用模块 (#267) + + * 完成系统调用模块重构 + + * 更新github workflow + +commit 660a04cef803fd73e9b294b30a96421b021a4b9b +Author: login +Date: Sat May 13 21:17:12 2023 +0800 + + 新增http server (#265) + + * 1.修复了当传入ahci驱动的缓冲区地址为用户缓冲区时,产生的内存越界问题.(采用分配内核缓冲区的方式临时解决) + 2.新增http server + + * 把libssl-dev添加到bootstrap.sh + + * http_server增加对父级相对路径的安全检查,防止访问系统内的其他文件 + + * 检查空指针情况 + + * 解决由于链接时,crt*.o未按照升序排列导致init段链接错误的问题 + +commit 49249f4ec94fad7baf923aed68d9a7b2da3de3d4 +Author: Bullet <93781792+GP-Bullet@users.noreply.github.com> +Date: Sat May 13 09:55:24 2023 +0800 + + 把调度器实例的裸指针改为Option (#262) + +commit bfafc102798ab1968ccf6b04315d8d3359a70ca8 +Author: login +Date: Thu May 11 17:41:42 2023 +0800 + + 修复读取stdin时,无法正常读取的问题。 (#264) + +commit 7285c927d95bb4b5c692c51a8f86c47009d07667 +Author: login +Date: Thu May 11 16:17:58 2023 +0800 + + 添加dadk支持 (#263) + + * 引入dadk,使用dadk0.1.1来编译test-relibc程序 + + * 由于gitee仓库体积限制导致无法继续使用gitee上的rust索引,因此更换为清华源 + + * github workflow的环境中,安装dadk + + * Auto configure dragonos rust toolchain + +commit b11bb1b25676f528ec1b0e1da0af82b4652f70c4 +Author: login +Date: Sun May 7 22:20:33 2023 +0800 + + 固定编译工具链、修复由于新版rust编译器问题导致的报错。 (#258) + + * 固定编译工具链、修复由于新版rust编译器问题导致的报错。 + + * 完善github workflow环境配置 + +``` \ No newline at end of file diff --git a/docs/community/ChangeLog/index.rst b/docs/community/ChangeLog/index.rst index 2e694c46b..d67695cd6 100644 --- a/docs/community/ChangeLog/index.rst +++ b/docs/community/ChangeLog/index.rst @@ -6,6 +6,7 @@ .. toctree:: :maxdepth: 1 + V0.1.x/V0.1.8 V0.1.x/V0.1.7 V0.1.x/V0.1.6 V0.1.x/V0.1.5 diff --git a/docs/community/contact/index.rst b/docs/community/contact/index.rst index 2abe7b258..35f7b0b4f 100644 --- a/docs/community/contact/index.rst +++ b/docs/community/contact/index.rst @@ -8,7 +8,7 @@ 社区公共邮箱:contact@DragonOS.org -DragonOS社区负责人: longjin +DragonOS社区负责人: 龙进 工作邮箱: longjin@DragonOS.org @@ -27,7 +27,7 @@ DragonOS是一个开源项目,我们欢迎任何形式的赞助和捐赠,您 您可以通过以下方式赞助和捐赠: - 访问DragonOS官网 https://DragonOS.org ,点击页面右上角的“赞助”按钮,进行捐赠 -- 联系社区负责人,沟通具体的赞助方式等。 +- 联系社区负责人,沟通具体的赞助方式等。联系方式:longjin@dragonos.org 财务及捐赠信息公开 ------------------------- diff --git a/docs/introduction/build_system.md b/docs/introduction/build_system.md index 38e91cd56..57dff27d0 100644 --- a/docs/introduction/build_system.md +++ b/docs/introduction/build_system.md @@ -19,7 +19,9 @@ cd DragonOS ``` :::{warning} -DragonOS的源代码托管在Github上,但是,由于Github在国内的访问速度较慢,因此,我们建议您在github上绑定您的电脑的**ssh公钥**, +DragonOS的源代码托管在Github上,但是,由于Github在国内的访问速度较慢。可能出现克隆失败的情况,这时只要重试即可。 + +当然,我们建议您在github上绑定您的电脑的**ssh公钥**, 然后通过以下命令来克隆代码,防止频繁出现git clone、pull、push失败的情况。 ```shell diff --git a/docs/introduction/features.md b/docs/introduction/features.md index 770711060..23bd951a6 100644 --- a/docs/introduction/features.md +++ b/docs/introduction/features.md @@ -90,6 +90,7 @@ - [x] 屏幕管理器 - [x] textui框架 - [x] CRC函数库 +- [x] 通知链 ### 系统调用 @@ -144,3 +145,4 @@ - [x] mpfr 4.1.1 [https://github.com/DragonOS-Community/mpfr](https://github.com/DragonOS-Community/mpfr) - [x] mpc 1.2.1 [https://github.com/DragonOS-Community/mpc](https://github.com/DragonOS-Community/mpc) - [x] relibc [https://github.com/DragonOS-Community/relibc](https://github.com/DragonOS-Community/relibc) +- [x] sqlite3 diff --git a/docs/introduction/mirrors.md b/docs/introduction/mirrors.md index 1b4ccf97b..17bf07204 100644 --- a/docs/introduction/mirrors.md +++ b/docs/introduction/mirrors.md @@ -2,5 +2,6 @@ 您可以从以下镜像站下载到DragonOS的源代码和其他文件: -- [DragonOS镜像站](https://mirrors.dragonos.org/) +- [DragonOS镜像站 https://mirrors.dragonos.org/](https://mirrors.dragonos.org/) - [DragonOS国内镜像站 (RinGoTek)](https://mirrors.RinGoTek.cn) +- [git镜像站](https://git.mirrors.dragonos.org/) diff --git a/kernel/src/arch/x86_64/cpu.rs b/kernel/src/arch/x86_64/cpu.rs index 1e15bc06c..ac1be208d 100644 --- a/kernel/src/arch/x86_64/cpu.rs +++ b/kernel/src/arch/x86_64/cpu.rs @@ -1,12 +1,13 @@ use core::arch::asm; -use super::asm::current::current_pcb; +use x86::cpuid::{cpuid, CpuIdResult}; /// @brief 获取当前cpu的apic id #[inline] pub fn current_cpu_id() -> u32 { - // TODO: apic重构后,使用apic id来设置这里 - current_pcb().cpu_id as u32 + let cpuid_res: CpuIdResult = cpuid!(0x1); + let cpu_id = (cpuid_res.ebx >> 24) & 0xff; + return cpu_id; } /// @brief 通过pause指令,让cpu休息一会儿。降低空转功耗 diff --git a/kernel/src/common/gfp.h b/kernel/src/common/gfp.h deleted file mode 100644 index ac4ee47d4..000000000 --- a/kernel/src/common/gfp.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include -#include -/** - * __GFP_ZERO: 获取内存的同时,将获取到的这块内存清空 - * - */ -#define __GFP_ZERO ((gfp_t)(1UL << 0)) \ No newline at end of file diff --git a/kernel/src/common/time.h b/kernel/src/common/time.h index 92a1417df..704e33022 100644 --- a/kernel/src/common/time.h +++ b/kernel/src/common/time.h @@ -5,44 +5,6 @@ // 操作系统定义时间以ns为单位 #define CLOCKS_PER_SEC 1000000 -struct tm -{ - int tm_sec; /* Seconds. [0-60] (1 leap second) */ - int tm_min; /* Minutes. [0-59] */ - int tm_hour; /* Hours. [0-23] */ - int tm_mday; /* Day. [1-31] */ - int tm_mon; /* Month. [0-11] */ - int tm_year; /* Year - 1900. */ - int tm_wday; /* Day of week. [0-6] */ - int tm_yday; /* Days in year.[0-365] */ - int tm_isdst; /* DST. [-1/0/1]*/ - - long int __tm_gmtoff; /* Seconds east of UTC. */ - const char *__tm_zone; /* Timezone abbreviation. */ -}; - -struct timespec -{ - int64_t tv_sec; // 秒 - int64_t tv_nsec; // 纳秒 -}; - -/** - * @brief 休眠指定时间 - * - * @param rqtp 指定休眠的时间 - * @param rmtp 返回的剩余休眠时间 - * @return int - */ -extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); - -/** - * @brief 睡眠指定时间 - * - * @param usec 微秒 - * @return int - */ -extern int usleep(useconds_t usec); /** * @brief 获取当前的CPU时间 diff --git a/kernel/src/filesystem/mod.rs b/kernel/src/filesystem/mod.rs index 8232d798f..c848c8979 100644 --- a/kernel/src/filesystem/mod.rs +++ b/kernel/src/filesystem/mod.rs @@ -3,6 +3,5 @@ pub mod fat; pub mod mbr; pub mod procfs; pub mod ramfs; -pub mod syscall; pub mod sysfs; pub mod vfs; diff --git a/kernel/src/filesystem/syscall.rs b/kernel/src/filesystem/syscall.rs deleted file mode 100644 index ea9f52898..000000000 --- a/kernel/src/filesystem/syscall.rs +++ /dev/null @@ -1,167 +0,0 @@ -use crate::{ - arch::asm::current::current_pcb, - filesystem::vfs::FileType, - kdebug, - syscall::{Syscall, SystemError}, - time::TimeSpec, -}; - -bitflags! { - /// 文件类型和权限 - pub struct ModeType: u32 { - /// 掩码 - const S_IFMT = 0o0_170_000; - /// 文件类型 - const S_IFSOCK = 0o140000; - const S_IFLNK = 0o120000; - const S_IFREG = 0o100000; - const S_IFBLK = 0o060000; - const S_IFDIR = 0o040000; - const S_IFCHR = 0o020000; - const S_IFIFO = 0o010000; - - const S_ISUID = 0o004000; - const S_ISGID = 0o002000; - const S_ISVTX = 0o001000; - /// 文件用户权限 - const S_IRWXU = 0o0700; - const S_IRUSR = 0o0400; - const S_IWUSR = 0o0200; - const S_IXUSR = 0o0100; - /// 文件组权限 - const S_IRWXG = 0o0070; - const S_IRGRP = 0o0040; - const S_IWGRP = 0o0020; - const S_IXGRP = 0o0010; - /// 文件其他用户权限 - const S_IRWXO = 0o0007; - const S_IROTH = 0o0004; - const S_IWOTH = 0o0002; - const S_IXOTH = 0o0001; - } -} - -#[repr(C)] -/// # 文件信息结构体 -pub struct PosixKstat { - /// 硬件设备ID - dev_id: u64, - /// inode号 - inode: u64, - /// 硬链接数 - nlink: u64, - /// 文件权限 - mode: ModeType, - /// 所有者用户ID - uid: i32, - /// 所有者组ID - gid: i32, - /// 设备ID - rdev: i64, - /// 文件大小 - size: i64, - /// 文件系统块大小 - blcok_size: i64, - /// 分配的512B块数 - blocks: u64, - /// 最后访问时间 - atime: TimeSpec, - /// 最后修改时间 - mtime: TimeSpec, - /// 最后状态变化时间 - ctime: TimeSpec, - /// 用于填充结构体大小的空白数据 - pub _pad: [i8; 24], -} -impl PosixKstat { - fn new() -> Self { - Self { - inode: 0, - dev_id: 0, - mode: ModeType { bits: 0 }, - nlink: 0, - uid: 0, - gid: 0, - rdev: 0, - size: 0, - atime: TimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - mtime: TimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - ctime: TimeSpec { - tv_sec: 0, - tv_nsec: 0, - }, - blcok_size: 0, - blocks: 0, - _pad: Default::default(), - } - } -} -impl Syscall { - fn do_fstat(fd: i32) -> Result { - let cur = current_pcb(); - match cur.get_file_ref_by_fd(fd) { - Some(file) => { - let mut kstat = PosixKstat::new(); - // 获取文件信息 - match file.metadata() { - Ok(metadata) => { - kstat.size = metadata.size as i64; - kstat.dev_id = metadata.dev_id as u64; - kstat.inode = metadata.inode_id as u64; - kstat.blcok_size = metadata.blk_size as i64; - kstat.blocks = metadata.blocks as u64; - - kstat.atime.tv_sec = metadata.atime.tv_sec; - kstat.atime.tv_nsec = metadata.atime.tv_nsec; - kstat.mtime.tv_sec = metadata.mtime.tv_sec; - kstat.mtime.tv_nsec = metadata.mtime.tv_nsec; - kstat.ctime.tv_sec = metadata.ctime.tv_sec; - kstat.ctime.tv_nsec = metadata.ctime.tv_nsec; - - kstat.nlink = metadata.nlinks as u64; - kstat.uid = metadata.uid as i32; - kstat.gid = metadata.gid as i32; - kstat.rdev = metadata.raw_dev as i64; - kstat.mode.bits = metadata.mode; - match file.file_type() { - FileType::File => kstat.mode.insert(ModeType::S_IFMT), - FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR), - FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK), - FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR), - FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK), - FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK), - FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO), - } - } - Err(e) => return Err(e), - } - - return Ok(kstat); - } - None => { - kdebug!("file not be opened"); - return Err(SystemError::EINVAL); - } - } - } - pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result { - match Self::do_fstat(fd) { - Ok(kstat) => { - if usr_kstat.is_null() { - return Err(SystemError::EFAULT); - } - unsafe { - *usr_kstat = kstat; - } - return Ok(0); - } - Err(e) => return Err(e), - } - } -} diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 0e4a1c1e0..d037e068f 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -162,7 +162,7 @@ pub trait IndexNode: Any + Sync + Send + Debug { } /// @brief 重新设置文件的大小 - /// + /// /// 如果文件大小增加,则文件内容不变,但是文件的空洞部分会被填充为0 /// 如果文件大小减小,则文件内容会被截断 /// diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 3c94947c6..d580623a0 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -7,6 +7,7 @@ use crate::{ io::SeekFrom, kerror, syscall::{Syscall, SystemError}, + time::TimeSpec, }; use super::{ @@ -22,6 +23,102 @@ pub const SEEK_CUR: u32 = 1; pub const SEEK_END: u32 = 2; pub const SEEK_MAX: u32 = 3; +bitflags! { + /// 文件类型和权限 + pub struct ModeType: u32 { + /// 掩码 + const S_IFMT = 0o0_170_000; + /// 文件类型 + const S_IFSOCK = 0o140000; + const S_IFLNK = 0o120000; + const S_IFREG = 0o100000; + const S_IFBLK = 0o060000; + const S_IFDIR = 0o040000; + const S_IFCHR = 0o020000; + const S_IFIFO = 0o010000; + + const S_ISUID = 0o004000; + const S_ISGID = 0o002000; + const S_ISVTX = 0o001000; + /// 文件用户权限 + const S_IRWXU = 0o0700; + const S_IRUSR = 0o0400; + const S_IWUSR = 0o0200; + const S_IXUSR = 0o0100; + /// 文件组权限 + const S_IRWXG = 0o0070; + const S_IRGRP = 0o0040; + const S_IWGRP = 0o0020; + const S_IXGRP = 0o0010; + /// 文件其他用户权限 + const S_IRWXO = 0o0007; + const S_IROTH = 0o0004; + const S_IWOTH = 0o0002; + const S_IXOTH = 0o0001; + } +} + +#[repr(C)] +/// # 文件信息结构体 +pub struct PosixKstat { + /// 硬件设备ID + dev_id: u64, + /// inode号 + inode: u64, + /// 硬链接数 + nlink: u64, + /// 文件权限 + mode: ModeType, + /// 所有者用户ID + uid: i32, + /// 所有者组ID + gid: i32, + /// 设备ID + rdev: i64, + /// 文件大小 + size: i64, + /// 文件系统块大小 + blcok_size: i64, + /// 分配的512B块数 + blocks: u64, + /// 最后访问时间 + atime: TimeSpec, + /// 最后修改时间 + mtime: TimeSpec, + /// 最后状态变化时间 + ctime: TimeSpec, + /// 用于填充结构体大小的空白数据 + pub _pad: [i8; 24], +} +impl PosixKstat { + fn new() -> Self { + Self { + inode: 0, + dev_id: 0, + mode: ModeType { bits: 0 }, + nlink: 0, + uid: 0, + gid: 0, + rdev: 0, + size: 0, + atime: TimeSpec { + tv_sec: 0, + tv_nsec: 0, + }, + mtime: TimeSpec { + tv_sec: 0, + tv_nsec: 0, + }, + ctime: TimeSpec { + tv_sec: 0, + tv_nsec: 0, + }, + blcok_size: 0, + blocks: 0, + _pad: Default::default(), + } + } +} impl Syscall { /// @brief 为当前进程打开一个文件 /// @@ -474,6 +571,66 @@ impl Syscall { } return Err(SystemError::EBADF); } + fn do_fstat(fd: i32) -> Result { + let cur = current_pcb(); + match cur.get_file_ref_by_fd(fd) { + Some(file) => { + let mut kstat = PosixKstat::new(); + // 获取文件信息 + match file.metadata() { + Ok(metadata) => { + kstat.size = metadata.size as i64; + kstat.dev_id = metadata.dev_id as u64; + kstat.inode = metadata.inode_id as u64; + kstat.blcok_size = metadata.blk_size as i64; + kstat.blocks = metadata.blocks as u64; + + kstat.atime.tv_sec = metadata.atime.tv_sec; + kstat.atime.tv_nsec = metadata.atime.tv_nsec; + kstat.mtime.tv_sec = metadata.mtime.tv_sec; + kstat.mtime.tv_nsec = metadata.mtime.tv_nsec; + kstat.ctime.tv_sec = metadata.ctime.tv_sec; + kstat.ctime.tv_nsec = metadata.ctime.tv_nsec; + + kstat.nlink = metadata.nlinks as u64; + kstat.uid = metadata.uid as i32; + kstat.gid = metadata.gid as i32; + kstat.rdev = metadata.raw_dev as i64; + kstat.mode.bits = metadata.mode; + match file.file_type() { + FileType::File => kstat.mode.insert(ModeType::S_IFMT), + FileType::Dir => kstat.mode.insert(ModeType::S_IFDIR), + FileType::BlockDevice => kstat.mode.insert(ModeType::S_IFBLK), + FileType::CharDevice => kstat.mode.insert(ModeType::S_IFCHR), + FileType::SymLink => kstat.mode.insert(ModeType::S_IFLNK), + FileType::Socket => kstat.mode.insert(ModeType::S_IFSOCK), + FileType::Pipe => kstat.mode.insert(ModeType::S_IFIFO), + } + } + Err(e) => return Err(e), + } + + return Ok(kstat); + } + None => { + return Err(SystemError::EINVAL); + } + } + } + pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result { + match Self::do_fstat(fd) { + Ok(kstat) => { + if usr_kstat.is_null() { + return Err(SystemError::EFAULT); + } + unsafe { + *usr_kstat = kstat; + } + return Ok(0); + } + Err(e) => return Err(e), + } + } } #[repr(C)] diff --git a/kernel/src/include/bindings/wrapper.h b/kernel/src/include/bindings/wrapper.h index f6cf2d59b..564e15fe8 100644 --- a/kernel/src/include/bindings/wrapper.h +++ b/kernel/src/include/bindings/wrapper.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/kernel/src/libs/rwlock.rs b/kernel/src/libs/rwlock.rs index 39917a9cb..cd357fe72 100644 --- a/kernel/src/libs/rwlock.rs +++ b/kernel/src/libs/rwlock.rs @@ -292,12 +292,19 @@ impl From for RwLock { } impl<'rwlock, T> RwLockReadGuard<'rwlock, T> { + /// @brief 释放守卫,获得保护的值的不可变引用 + /// + /// ## Safety + /// + /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确, + /// 因此必须小心的手动维护好preempt count。 + /// + /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。 #[allow(dead_code)] #[inline] - /// @brief 释放守卫,获得保护的值的不可变引用 - pub fn leak(this: Self) -> &'rwlock T { - let Self { data, .. } = this; - return unsafe { &*data }; + pub unsafe fn leak(this: Self) -> &'rwlock T { + let this = ManuallyDrop::new(this); + return unsafe { &*this.data }; } } @@ -363,9 +370,16 @@ impl<'rwlock, T> RwLockUpgradableGuard<'rwlock, T> { #[allow(dead_code)] #[inline] - /// @brief 返回内部数据的引用,消除锁 - pub fn leak(this: Self) -> &'rwlock T { - let this = ManuallyDrop::new(this); + /// @brief 返回内部数据的引用,消除守卫 + /// + /// ## Safety + /// + /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确, + /// 因此必须小心的手动维护好preempt count。 + /// + /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。 + pub unsafe fn leak(this: Self) -> &'rwlock T { + let this: ManuallyDrop> = ManuallyDrop::new(this); unsafe { &*this.data } } @@ -374,8 +388,15 @@ impl<'rwlock, T> RwLockUpgradableGuard<'rwlock, T> { impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> { #[allow(dead_code)] #[inline] - /// @brief 返回内部数据的引用,消除锁 - pub fn leak(this: Self) -> &'rwlock T { + /// @brief 返回内部数据的引用,消除守卫 + /// + /// ## Safety + /// + /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确, + /// 因此必须小心的手动维护好preempt count。 + /// + /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。 + pub unsafe fn leak(this: Self) -> &'rwlock T { let this = ManuallyDrop::new(this); return unsafe { &*this.data }; diff --git a/kernel/src/libs/spinlock.rs b/kernel/src/libs/spinlock.rs index b3548778b..1108b12f8 100644 --- a/kernel/src/libs/spinlock.rs +++ b/kernel/src/libs/spinlock.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] use core::cell::UnsafeCell; +use core::mem::ManuallyDrop; use core::ops::{Deref, DerefMut}; use core::ptr::read_volatile; @@ -107,6 +108,11 @@ impl RawSpinlock { self.0.store(false, Ordering::Release); } + /// 解锁,但是不更改preempt count + unsafe fn unlock_no_preempt(&self) { + self.0.store(false, Ordering::Release); + } + /// @brief 放锁并开中断 pub fn unlock_irq(&self) { self.unlock(); @@ -170,6 +176,24 @@ pub struct SpinLockGuard<'a, T: 'a> { flag: usize, } +impl<'a, T: 'a> SpinLockGuard<'a, T> { + /// 泄露自旋锁的守卫,返回一个可变的引用 + /// + /// ## Safety + /// + /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确, + /// 因此必须小心的手动维护好preempt count。 + /// + /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。 + #[inline] + pub unsafe fn leak(this: Self) -> &'a mut T { + // Use ManuallyDrop to avoid stacked-borrow invalidation + let this = ManuallyDrop::new(this); + // We know statically that only we are referencing data + unsafe { &mut *this.lock.data.get() } + } +} + /// 向编译器保证,SpinLock在线程之间是安全的. /// 其中要求类型T实现了Send这个Trait unsafe impl Sync for SpinLock where T: Send {} @@ -223,6 +247,16 @@ impl SpinLock { } return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); } + + /// 强制解锁,并且不更改preempt count + /// + /// ## Safety + /// + /// 由于这样做可能导致preempt count不正确,因此必须小心的手动维护好preempt count。 + /// 如非必要,请不要使用这个函数。 + pub unsafe fn force_unlock(&self) { + self.lock.unlock_no_preempt(); + } } /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用 diff --git a/kernel/src/mm/gfp.rs b/kernel/src/mm/gfp.rs deleted file mode 100644 index 2f4cba54e..000000000 --- a/kernel/src/mm/gfp.rs +++ /dev/null @@ -1,5 +0,0 @@ -use crate::include::bindings::bindings::gfp_t; - -#[allow(unused_parens)] -/// 定义__GFP_ZERO -pub const __GFP_ZERO: gfp_t = (1 << 0); diff --git a/kernel/src/mm/mm.h b/kernel/src/mm/mm.h index 8dec99b0f..98536e8b6 100644 --- a/kernel/src/mm/mm.h +++ b/kernel/src/mm/mm.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include @@ -47,14 +46,6 @@ extern uint64_t rs_unmap_at_low_addr(); #define LOCAL_APIC_MAPPING_OFFSET 0xfee00000UL #define AHCI_MAPPING_OFFSET 0xff200000UL // AHCI 映射偏移量,之后使用了4M的地址 -// ===== 内存区域属性 ===== -// DMA区域 -#define ZONE_DMA (1 << 0) -// 已在页表中映射的区域 -#define ZONE_NORMAL (1 << 1) -// 未在页表中映射的区域 -#define ZONE_UNMAPPED_IN_PGT (1 << 2) - // ===== 页面属性 ===== // 页面在页表中已被映射 mapped=1 unmapped=0 #define PAGE_PGT_MAPPED (1 << 0) diff --git a/kernel/src/mm/mod.rs b/kernel/src/mm/mod.rs index 8364e3c9f..cfe111f1d 100644 --- a/kernel/src/mm/mod.rs +++ b/kernel/src/mm/mod.rs @@ -23,11 +23,11 @@ use self::{ pub mod allocator; pub mod c_adapter; -pub mod gfp; pub mod kernel_mapper; pub mod mmio_buddy; pub mod no_init; pub mod page; +pub mod percpu; pub mod syscall; pub mod ucontext; diff --git a/kernel/src/mm/percpu.rs b/kernel/src/mm/percpu.rs new file mode 100644 index 000000000..b2c2b2ee0 --- /dev/null +++ b/kernel/src/mm/percpu.rs @@ -0,0 +1,90 @@ +use core::sync::atomic::AtomicUsize; + +use alloc::vec::Vec; + +use crate::{ + include::bindings::bindings::smp_get_total_cpu, libs::lazy_init::Lazy, + smp::core::smp_get_processor_id, +}; + +/// 系统中的CPU数量 +/// +/// todo: 待smp模块重构后,从smp模块获取CPU数量。 +/// 目前由于smp模块初始化时机较晚,导致大部分内核模块无法在早期初始化PerCpu变量。 +const CPU_NUM: AtomicUsize = AtomicUsize::new(PerCpu::MAX_CPU_NUM); + +#[derive(Debug)] +pub struct PerCpu; + +impl PerCpu { + pub const MAX_CPU_NUM: usize = 128; + /// # 初始化PerCpu + /// + /// 该函数应该在内核初始化时调用一次。 + /// + /// 该函数会调用`smp_get_total_cpu()`获取CPU数量,然后将其存储在`CPU_NUM`中。 + #[allow(dead_code)] + pub fn init() { + if CPU_NUM.load(core::sync::atomic::Ordering::SeqCst) != 0 { + panic!("PerCpu::init() called twice"); + } + let cpus = unsafe { smp_get_total_cpu() } as usize; + assert!(cpus > 0, "PerCpu::init(): smp_get_total_cpu() returned 0"); + CPU_NUM.store(cpus, core::sync::atomic::Ordering::SeqCst); + } +} + +/// PerCpu变量 +/// +/// 该结构体的每个实例都是线程安全的,因为每个CPU都有自己的变量。 +/// +/// 一种简单的使用方法是:使用该结构体提供的`define_lazy`方法定义一个全局变量, +/// 然后在内核初始化时调用`init`、`new`方法去初始化它。 +/// +/// 当然,由于Lazy有运行时开销,所以也可以直接全局声明一个Option, +/// 然后手动初始化然后赋值到Option中。(这样需要在初始化的时候,手动确保并发安全) +#[derive(Debug)] +#[allow(dead_code)] +pub struct PerCpuVar { + inner: Vec, +} + +#[allow(dead_code)] +impl PerCpuVar { + /// # 初始化PerCpu变量 + /// + /// ## 参数 + /// + /// - `data` - 每个CPU的数据的初始值。 传入的Vec的长度必须等于CPU的数量,否则返回None。 + pub fn new(data: Vec) -> Option { + let cpu_num = CPU_NUM.load(core::sync::atomic::Ordering::SeqCst); + if cpu_num == 0 { + panic!("PerCpu::init() not called"); + } + + if data.len() != cpu_num { + return None; + } + + return Some(Self { inner: data }); + } + + /// 定义一个Lazy的PerCpu变量,稍后再初始化 + pub const fn define_lazy() -> Lazy { + Lazy::::new() + } + + pub fn get(&self) -> &T { + let cpu_id = smp_get_processor_id(); + &self.inner[cpu_id as usize] + } + + pub fn get_mut(&mut self) -> &mut T { + let cpu_id = smp_get_processor_id(); + &mut self.inner[cpu_id as usize] + } +} + +/// PerCpu变量是线程安全的,因为每个CPU都有自己的变量。 +unsafe impl Sync for PerCpuVar {} +unsafe impl Send for PerCpuVar {} diff --git a/kernel/src/mm/syscall.rs b/kernel/src/mm/syscall.rs index 233d858a1..48b2aafd8 100644 --- a/kernel/src/mm/syscall.rs +++ b/kernel/src/mm/syscall.rs @@ -78,7 +78,7 @@ impl Syscall { if new_addr == address_space.brk { return Ok(address_space.brk); } - + unsafe { address_space .set_brk(VirtAddr::new(page_align_up(new_addr.data()))) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 626f92fec..ee12c2e7e 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -7,11 +7,10 @@ use num_traits::{FromPrimitive, ToPrimitive}; use crate::{ arch::{cpu::cpu_reset, MMArch}, - filesystem::syscall::PosixKstat, filesystem::vfs::{ fcntl::FcntlCommand, file::FileMode, - syscall::{SEEK_CUR, SEEK_END, SEEK_MAX, SEEK_SET}, + syscall::{PosixKstat, SEEK_CUR, SEEK_END, SEEK_MAX, SEEK_SET}, MAX_PATHLEN, }, include::bindings::bindings::{pid_t, PAGE_2M_SIZE, PAGE_4K_SIZE}, diff --git a/tools/bootstrap.sh b/tools/bootstrap.sh index 09e5611be..a6d7347a5 100644 --- a/tools/bootstrap.sh +++ b/tools/bootstrap.sh @@ -139,6 +139,7 @@ rustInstall() { rustup toolchain install nightly rustup default nightly rustup component add rust-src + rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu rustup component add llvm-tools-preview rustup target add x86_64-unknown-none cargo install dadk diff --git a/user/apps/about/about.c b/user/apps/about/about.c index b049a784a..f00524722 100644 --- a/user/apps/about/about.c +++ b/user/apps/about/about.c @@ -18,7 +18,7 @@ void print_copyright() printf(" DragonOS - An opensource operating system.\n"); printf(" Copyright: fslongjin & DragonOS Community. 2022-2023, All rights reserved.\n"); printf(" Version: "); - put_string("V0.1.7\n", COLOR_GREEN, COLOR_BLACK); + put_string("V0.1.8\n", COLOR_GREEN, COLOR_BLACK); printf(" Git commit SHA1: %s\n", DRAGONOS_GIT_COMMIT_SHA1); printf(" Build time: %s %s\n", __DATE__, __TIME__); printf(" \nYou can visit the project via:\n");