Conversation
=== The fundamental problem Circular dependencies: axdriver → axdma → axmm → axfs → axdriver Fix Policy Break the two edges in the loop (axdma → axmm and axdriver → axmm) by decoupling them with crate_interface, and change axmm → axfs to optional. Change log (13 files) 1. Decouple axdma → axmm using crate_interface modules/axdma/Cargo.toml — Remove the axmm dependency and add crate_interface modules/axdma/src/lib.rs — Defines the DmaProtectIf trait (crate_interface: def_interface) modules/axdma/src/dma.rs — Replace axmm::kernel_aspace() with call_interface! (DmaProtectIf: protect_memory(...)) lock() protect(...). 2. Decouple axdriver → axmm using crate_interface modules/axdriver/Cargo.toml — Remove axmm from dyn features and dependencies modules/axdriver/src/dyn_drivers/klib.rs — Defines the IoMapIf trait, replacing axmm::iomap(...) with call_interface! (IoMapIf: iomap(...)) 3. Change axmm → axfs to optional modules/axmm/Cargo.toml — Added fs feature, changing axfs/axfs-ng-vfs to optional modules/axmm/src/backend/mod.rs — Protects the cow and file modules and enum variants with #[cfg (feature = fs)] 4. Implement the interface in axruntime modules/axruntime/Cargo.toml — Added DMA feature (axdma enabled), driver-dyn supports paging, fs supports axmm?/fs modules/axruntime/src/lib.rs — Implements DmaProtectIf (axmm:kernel_aspace) and IoMapIf (axmm:iomap) 5. Feature Transmission api/axfeat/Cargo.toml — DMA feature added to axruntime/dma api/arceos_api/Cargo.toml — fs feature added to axmm? /fs 6. Fixed const compatibility issues in the new Rust toolchain ulib/axstd/Cargo.toml — Add spin dependencies ulib/axstd/src/io/stdio.rs — Uses spin::Lazy to statically initialize BufReader
======== 1. modules/axconfig/src/lib.rs Fallback path: Change from ../../configs/dummy.toml to dummy.toml. The original path points to Configs/dummy.toml outside the crate directory, which does not exist after packaging. Move it directly to the crate directory. 2. modules/axconfig/dummy.toml (new) Copy the config file from config/dummy.toml to the axconfig crate directory, ensuring the packaged crate includes the fallback configuration file. 3. modules/axconfig/Cargo.toml Add README.md. Add the following files: [src/**/*, build.rs, dummy.toml, Cargo.toml, README.md], ensuring dummy.toml is included in the.crate file. 4. modules/axconfig/README.md (new) The README documentation required by crates.io. The cargo build-p axconfig command in workspace can also pass without affecting the existing development workflow.
===========
cargo publish-p axalloc--dry-run has passed, and cargo build-p axalloc in the workspace can be compiled normally.
1. modules/axalloc/Cargo.toml
Dependency: allocator = {workspace = true, features = [bitmap]} changed to
axallocator = {version = 0.1.3-preview.1,default-features = false,features = [bitmap]} (modified to align with crates.io's ax allocator to meet release requirements).
Features: All allocator/... will be renamed to ax allocator/... (e.g., ax allocator/page-alloc-256m, ax allocator/tlsf, etc.).
readme: Added readme = README.md.
2. modules/axalloc/src/lib.rs
use allocator: {...} changed to use axallocator: {...}.
allocator:: SlabByte Allocator / BuddyByte Allocator / TlsfByte Allocator changed to ax allocator::...
The allocator in the file annotation: TlsfByte Allocator has been renamed to axallocator: TlsfByte Allocator.
3. modules/axalloc/src/page.rs
axallocator: The AllocError cannot be automatically converted to AxError. Modify the two alloc_pages (...) to
Map error (|_| AxError: NoMemory)?, and use axerrno: {AxError, AxResult}.
4. modules/axalloc/README.md (new file)
A brief description, feature list, and license for crates.io.
Note: axalloc now depends on the ax allocator 0.1.3-preview.1 from crates.io. If this version has not been released, you must release the allocator (ax allocator) before releasing axalloc.
========== Root cause: The API between the axplat version (0.3.0) on crates.io and the git dev-v03 branch differs. - crates.io 0.3.0 does not have the percpu module - The MemIf in crate.io 0.3.0 does not support the kernel_aspace method - The PowerIf method in crates.io 0.3.0 requires the cpu_num method Modified three files (located in /home/chyyuu/thecodes/publisharceos/arceos/modules/axhal/src/): - percpu.rs Enables pub use axplat::percpu::*; conditional gate control via #[cfg (any (feature = defplat, feature = myplat))]. These features are disabled during dry-run, preventing compilation of non-existent modules. During build, defplat is enabled, and the git version of axplat used through patch includes the percpu module. - mem.rs Isolate the re-export of kernel_aspace from the main import, similarly controlled by #[cfg (any (feature = defplat, feature = myplat))]. - dummy.rs Removes kernel_aspace (a feature absent in 0.3.0) from impl MemIf for DummyMem, and adds cpu_num() -> usize (a feature required in 0.3.0) to impl PowerIf for DummyPower. dummy.rs is compiled only on non-embedded targets (e.g., x86_64 host for dry-run) and does not affect make builds. Verification result: cargo publish -p axhal --dry-run --allow-dirty # Successfully completed make A=examples/helloworld ARCH=riscv64 LOG=info run # Successfully executed and output Hello, world!
==========
Modified 1 file and added 1 file (both located in /home/chyyuu/thecodes/publisharceos/arceos/modules/axtask/):
1. Modify Cargo.toml
- Add readme = README.md
- Change axconfig = {workspace = true, optional = true} to axconfig = {version = 0.2.1-preview.1, optional = true} (axconfig is already on crates.io)
- Replace with (axhal is available on crates.io)
- In the dev-dependencies, axhal is also updated to version dependency {version = 0.2.1-preview.1, features = [fp-simd]}
- In dev-dependencies, axtask's auto-reference is changed to {path = ., features = [test, multitask]}
Other workspace dependencies (e.g., axerrno, cfg-if, log, axpoll) are already versioned in the workspace definition. Setting workspace = true correctly interprets these as versioned dependencies, eliminating the need for modification.
2. Added README.md
A README file was created to describe the functions and features of the axtask module. Verification results:
- cargo publish-p axtask--dry-run--allow-dirty — Successfully completed (downloaded axhal 0.2.1-preview.1 from crates.io and compiled it)
- make A=examples/helloworld ARCH=riscv64 LOG=info run — Successfully executed and output Hello, world! (workspace's [patch.crates-io] automatically redirects axconfig and axhal to the local path)
There was a problem hiding this comment.
Pull request overview
This PR addresses circular dependency issues in the ArceOS module structure by breaking the dependency cycle: axdriver → axdma → axmm → axfs → axdriver. The solution employs the crate_interface pattern to decouple modules and feature flags to make filesystem dependencies optional.
Changes:
- Decoupled axdma → axmm and axdriver → axmm using
crate_interfacewith implementations in axruntime - Made axmm → axfs optional via feature flags to allow axmm to function without filesystem support
- Updated module versions and dependency specifications for crates.io publication readiness
- Fixed Rust toolchain compatibility issue using
spin::Lazyfor static initialization
Reviewed changes
Copilot reviewed 30 out of 31 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| modules/axdma/src/lib.rs | Defines DmaProtectIf interface to decouple from axmm |
| modules/axdma/src/dma.rs | Replaces direct axmm calls with interface calls |
| modules/axdma/Cargo.toml | Removes axmm dependency, adds crate_interface |
| modules/axdriver/src/dyn_drivers/klib.rs | Defines IoMapIf interface to decouple from axmm |
| modules/axdriver/Cargo.toml | Removes axmm dependency |
| modules/axruntime/src/lib.rs | Implements DmaProtectIf and IoMapIf interfaces |
| modules/axruntime/Cargo.toml | Adds dma feature and driver-dyn paging requirement |
| modules/axmm/src/backend/mod.rs | Guards fs-dependent backends with feature flags |
| modules/axmm/Cargo.toml | Makes axfs dependencies optional with fs feature |
| api/axfeat/Cargo.toml | Adds dma feature propagation |
| api/arceos_api/Cargo.toml | Adds axmm fs feature propagation |
| ulib/axstd/src/io/stdio.rs | Uses spin::Lazy for const initialization compatibility |
| ulib/axstd/Cargo.toml | Adds spin dependency |
| modules/axhal/src/dummy.rs | Removes kernel_aspace from dummy implementation |
| modules/axhal/src/mem.rs | Conditionally exports kernel_aspace |
| modules/axhal/src/percpu.rs | Conditionally exports percpu module |
| modules/axhal/Cargo.toml | Updates to version specifications for publishing |
| modules/axalloc/src/lib.rs | Renames allocator to axallocator |
| modules/axalloc/src/page.rs | Improves error handling for page allocation |
| modules/axalloc/Cargo.toml | Updates allocator dependency to axallocator version |
| modules/axtask/Cargo.toml | Updates to version specifications |
| modules/axconfig/src/lib.rs | Updates fallback path to local dummy.toml |
| modules/axconfig/dummy.toml | Adds dummy configuration for standalone builds |
| modules/axconfig/Cargo.toml | Adds include directive for dummy.toml and README |
| modules/PUBLISH_ORDER.md | Documents crates.io publication order |
| Cargo.toml | Updates workspace version and adds patch section |
| Cargo.lock | Reflects all dependency updates |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #[crate_interface::impl_interface] | ||
| impl axdriver::dyn_drivers::klib::IoMapIf for IoMapIfImpl { | ||
| fn iomap( | ||
| paddr: memory_addr::PhysAddr, | ||
| size: usize, | ||
| ) -> Result<memory_addr::VirtAddr, axerrno::AxError> { | ||
| axmm::iomap(paddr, size) |
There was a problem hiding this comment.
The function axmm::iomap does not exist in the axmm module. This will cause a compilation error when the driver-dyn feature is enabled. The axmm module needs to provide an iomap function that wraps the kernel address space's map_linear method to map physical addresses for IO access.
| #[crate_interface::impl_interface] | |
| impl axdriver::dyn_drivers::klib::IoMapIf for IoMapIfImpl { | |
| fn iomap( | |
| paddr: memory_addr::PhysAddr, | |
| size: usize, | |
| ) -> Result<memory_addr::VirtAddr, axerrno::AxError> { | |
| axmm::iomap(paddr, size) | |
| fn iomap( | |
| paddr: memory_addr::PhysAddr, | |
| size: usize, | |
| ) -> Result<memory_addr::VirtAddr, axerrno::AxError> { | |
| axmm::kernel_aspace() | |
| .lock() | |
| .map_linear(paddr, size) | |
| } | |
| #[cfg(feature = "driver-dyn")] | |
| #[crate_interface::impl_interface] | |
| impl axdriver::dyn_drivers::klib::IoMapIf for IoMapIfImpl { | |
| fn iomap( | |
| paddr: memory_addr::PhysAddr, | |
| size: usize, | |
| ) -> Result<memory_addr::VirtAddr, axerrno::AxError> { | |
| iomap(paddr, size) |
==========
1. Modify /home/chyyuu/thecodes/publisharceos/arceos/modules/axsync/Cargo.toml
Add README.md.
Replace axtask/workspace = true with axtask = {version = 0.2.1-preview.1} (parsed from crates.io after release).
dev-dependencies: axsync is updated to {path = ., features = [multitask]} and axtask to {version = 0.2.1-preview.1, features = [test]}.
2. Added /home/chyyuu/thecodes/publisharceos/arceos/modules/axsync/README.md
The module description, provided synchronization primitives, and feature descriptions have been written.
3. Modify /home/chyyuu/thecodes/publisharceos/arceos/Cargo.toml
Add to [patch.crates-io]:
axtask = { path = modules/axtask }
axsync = { path = modules/axsync }
This approach utilizes the local axtask/axsync during workspace setup, eliminating the need for crates.io axtask in make run.
Verification results
make A=examples/helloworld ARCH=riscv64 LOG=info run: Passed, successfully outputs Hello, world!
cargo publish-p axsync--dry-run: Passed.
============== axipi relies on axhal and enables the IPI feature (→irq). The released axhal 0.2.1-preview.1 is API incompatible with axplat 0.3.0 on crates.io when irq is enabled (irq_num, handle(), return type, ConsoleIf::irq_num, etc.). It is necessary to fix axhal and release a new version. Modified file 1. modules/axhal/Cargo.toml — Upgrade to version 0.2.2-preview.1 (independent of workspace version), remove the redundant axplat-0_3 feature, and restore default to [] 2. modules/axhal/src/dummy.rs — Compatible with axplat 0.3.0 API: ConsoleIf: Remove irq_num (not available in version 0.3.0) MemIf: Remove kernel_aspace (not available in 0.3.0) TimeIf: set_oneshot_timer restore #[cfg (feature = "irq")] PowerIf: Add cpu_num() (required in 0.3.0) IrqIf: handle: return () (0.3.0 signature) 3. modules/axhal/src/time.rs — set_oneshot_timer directly re-exported from axplat via #[cfg (feature = "irq")]; irq_num controlled by defplat/myplat (this API was not available in version 0.3.0). 4. modules/axhal/src/lib.rs — The console module uses defplat/myplat to control irq_num, providing a stub when no platform is detected. 5. modules/axhal/src/irq.rs — handle() function (defplat/myplat gate control, with git version returning Option<usize> and 0.3.0 version returning (). 6. modules/axhal/src/percpu.rs — axplat::percpu::* gateway control + this_cpu_id() stub. Test Results cargo publish-p axhal--dry-run # passed
==========
Modified files (all in /home/chyyuu/thecodes/publisharceos/arceos)
1. modules/axdma/Cargo.toml — Prepare for release
Add description (required for crates.io)
allocator (Git dependency) → ax allocator = "0.1.3-preview.1" (crates.io)
axalloc, axconfig, and axhal have been updated from workspace = true (path-dependent) to explicit crates.io version numbers
Add page_table_multiarch = "0.5" (direct dependency, used for MappingFlags)
Disable axhal's paging feature to prevent compilation issues on crates.io
2. modules/axdma/src/lib.rs — Update import
use allocator::AllocResult → use axallocator::AllocResult
use axhal::paging::MappingFlags → use page_table_multiarch::MappingFlags
3. modules/axdma/src/dma.rs — Update imports and fix macro paths
use allocator::{...} → use axallocator::{...}
use axhal:: {mem:: virt_to_phys, paging:: MappingFlags} split into two lines
call_interface! (DmaProtectIf:...) → call_interface! (crate: DmaProtectIf:...) fixes cross-module paths
4. modules/axhal/Cargo.toml, modules/axtask/Cargo.toml, modules/axsync/Cargo.toml, modules/axipi/Cargo.toml — fixes pre-release version patch issues
Update the version reference from "0.2.1-preview.1" to "0.2.2-preview.1" to ensure [patch.crates-io] matches the local version.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 38 out of 39 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 41 out of 42 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| axhal = { workspace = true, features = ["paging"] } | ||
| axmm.workspace = true | ||
| axhal = { version = "0.2.2-preview.2" } | ||
| page_table_multiarch = { version = "0.5" } |
There was a problem hiding this comment.
The page_table_multiarch dependency should include the "axerrno" feature for consistency with axhal and to ensure proper error type conversions. While not strictly required since axdma uses axerrno::AxError directly, it's best practice to be consistent across modules that use page_table_multiarch.
| page_table_multiarch = { version = "0.5" } | |
| page_table_multiarch = { version = "0.5", features = ["axerrno"] } |
…t in the Send method of accept(). First, clone the Receiver, release the lock, and then await.
==========
In the [workspace_dependencies] section of arceos/Cargo.toml, add version = "0.2.2-preview.1" to arceos_api. Both dry-run and production releases passed without additional modifications.
In the [workspace_dependencies] section of arceos/Cargo.toml, add version = "0.2.2-preview.1" to axstd. Both dry-run and release builds passed on the first attempt.
The issue is that build.rs uses the relative path../../ulib/axlibc/include/ to reference external header files, which is not present in the cargo publish sandbox. The solution is:
Skip generating build.rs when external header files are unavailable (use pre-generated files)
Ensure that certgen.rs is included in the release package
The build script does not allow modifying the source directory during publish verification. Modify it to write to OUT_DIR.
arceos/Cargo.toml-for arceos_posix_api with version = "0.2.2-preview.1"
arceos_posix_api/build.rs-Join condition check: If the external header file directory../../ulib/axlibc/include/ does not exist (e.g., in a cargo publish sandbox), skip regenerating ctypes_gen.rs and use the pre-generated version
arceos_posix_api/.gitignore-Clear content to ensure ctypes_gen.rs is included in the release package
arceos_posix_api/src/imp/stdio.rs-Fixed the BufReader::new issue in axio 0.3.0-pre.1 where it was no longer a const function, using spin::Once to delay initialization
arceos/Cargo.toml-Add version = "0.2.2-preview.1" to axlibc
axlibc/build.rs-Write libctypes_gen.rs to OUT_DIR instead of src/, avoiding the publish verification restriction on source directory modifications
axlibc/lib.rs-Use include! (concat! (env! ("OUT_DIR"), "/libctypes_gen.rs")) to import the generated binding file from OUT_DIR
=============== arceos/modules/axhal/Cargo.toml — version 0.2.2-preview.4, tighten the axplat/axcpu/platform crate dependencies arceos/modules/axhal/src/dummy.rs — Aligns the axplat v0.3.0-preview.2 API (adding kernel_aspace and removing cpu_num) arceos/modules/axruntime/Cargo.toml — version 0.2.2-preview.2, tighten the axplat dependency arceos/Cargo.toml — change patches to local paths and update version numbers Verification result: make A=examples/helloworld ARCH=riscv64 LOG=info run — succeeded cargo run--release (no git patches) — succeeded in the app-helloworld directory
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 50 out of 51 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #[cfg(not(any(feature = "defplat", feature = "myplat")))] | ||
| { | ||
| handle(vector); | ||
| let hook = IRQ_HOOK.load(Ordering::SeqCst); | ||
| if hook != 0 { | ||
| let hook = unsafe { core::mem::transmute::<usize, fn(usize)>(hook) }; | ||
| hook(vector); | ||
| } | ||
| } |
There was a problem hiding this comment.
There's an inconsistency in the IRQ hook behavior between real platforms and the dummy platform. With real platforms (lines 43-48), the hook receives the IRQ number returned by handle(vector). With the dummy platform (lines 52-57), the hook receives the raw vector parameter instead. This could cause subtle bugs if code relies on the hook receiving a consistent value. Consider either:
- Making the dummy
handle()returnOption<usize>and treatingNoneas no-op, or - Documenting that the hook receives different values depending on the platform
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 51 out of 52 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| axklib::mem::iomap(addr, size) | ||
| .map_err(|e| match e { | ||
| AxError::NoMemory => OnProbeError::KError(rdrive::KError::NoMem), | ||
| AxErrorKind::NoMemory => OnProbeError::KError(rdrive::KError::NoMem), | ||
| _ => OnProbeError::Other(alloc::format!("{e:?}").into()), |
There was a problem hiding this comment.
axklib::mem::iomap() returns an AxResult whose error type comes from axklib’s axerrno dependency (Cargo.lock shows axklib depends on axerrno 0.1.2). Matching that error value directly against axerrno::AxErrorKind::NoMemory from this crate is very likely a type mismatch and will fail to compile. Consider matching on the actual error type returned by axklib (or extracting/converting to an error kind, e.g. via an accessor) before mapping it to OnProbeError.
| #[crate_interface::def_interface] | ||
| pub trait IoMapIf { | ||
| /// Map a physical memory region for IO access. | ||
| fn iomap(paddr: PhysAddr, size: usize) -> AxResult<VirtAddr>; | ||
| } |
There was a problem hiding this comment.
IoMapIf::iomap is defined to return axklib::AxResult, which (per current Cargo.lock) uses axerrno 0.1.2 via the axklib dependency. This makes the interface’s error type effectively tied to an older axerrno, and can lead to cross-crate type incompatibilities when the implementor (e.g. axruntime/axmm) uses the workspace axerrno (0.2.x). Consider redefining this interface in terms of the workspace error type (e.g. axerrno::AxError/axerrno::AxResult) or otherwise ensuring axklib and the rest of the workspace share the same axerrno version.
| impl axdriver::dyn_drivers::klib::IoMapIf for IoMapIfImpl { | ||
| fn iomap( | ||
| paddr: memory_addr::PhysAddr, | ||
| size: usize, | ||
| ) -> Result<memory_addr::VirtAddr, axerrno::AxError> { | ||
| axmm::iomap(paddr, size) | ||
| } |
There was a problem hiding this comment.
The IoMapIf implementation returns Result<..., axerrno::AxError> from the workspace axerrno, but the trait method is declared to return axklib::AxResult in axdriver::dyn_drivers::klib. With the current dependency graph (Cargo.lock shows axklib depends on axerrno 0.1.2), this can become a hard type mismatch and fail to compile. Align the trait signature and this impl to use the same concrete error type/version (either update axklib/axerrno versions to match, or avoid axklib::AxResult in the interface).
===
The fundamental problem
Circular dependencies: axdriver → axdma → axmm → axfs → axdriver Fix Policy
Break the two edges in the loop (axdma → axmm and axdriver → axmm) by decoupling them with crate_interface, and change axmm → axfs to optional. Change log (13 files)
ulib/axstd/src/io/stdio.rs — Uses spin::Lazy to statically initialize BufReader