Skip to content

Commit

Permalink
Merge pull request #2 from arceos-org/merge_memory_set
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 authored Aug 20, 2024
2 parents b81b821 + 9cdeaa0 commit 41b0864
Show file tree
Hide file tree
Showing 15 changed files with 948 additions and 36 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@ jobs:
contents: write
env:
default-branch: ${{ format('refs/heads/{0}', github.event.repository.default_branch) }}
RUSTDOCFLAGS: -D rustdoc::broken_intra_doc_links -D missing-docs
RUSTDOCFLAGS: -Zunstable-options --enable-index-page -D rustdoc::broken_intra_doc_links -D missing-docs
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- name: Build docs
continue-on-error: ${{ github.ref != env.default-branch && github.event_name != 'pull_request' }}
run: |
cargo doc --no-deps --all-features
printf '<meta http-equiv="refresh" content="0;url=%s/index.html">' $(cargo tree | head -1 | cut -d' ' -f1) > target/doc/index.html
- name: Deploy to Github Pages
if: ${{ github.ref == env.default-branch }}
uses: JamesIves/github-pages-deploy-action@v4
Expand Down
22 changes: 13 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
[package]
name = "memory_addr"
version = "0.2.1"
[workspace]
resolver = "2"

members = [
"memory_addr",
"memory_set",
]

[workspace.package]
version = "0.3.0-dev" # dev here to avoid publishing it mistakenly, as `memory_set` is not updated yet
edition = "2021"
authors = ["Yuekai Jia <[email protected]>"]
description = "Wrappers and helper functions for physical and virtual addresses"
authors = ["Yuekai Jia <[email protected]>", "aarkegz <[email protected]>"]
license = "GPL-3.0-or-later OR Apache-2.0 OR MulanPSL-2.0"
homepage = "https://github.com/arceos-org/arceos"
# documentation = "let member have their own documentation links"
repository = "https://github.com/arceos-org/memory_addr"
documentation = "https://docs.rs/memory_addr"
keywords = ["arceos", "address", "virtual-memory"]
# keywords = ["let member have their own keywords"]
categories = ["os", "memory-management", "no-std"]

[dependencies]
30 changes: 5 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
# memory_addr
# `memory_addr`

[![Crates.io](https://img.shields.io/crates/v/memory_addr)](https://crates.io/crates/memory_addr)
[![Docs.rs](https://docs.rs/memory_addr/badge.svg)](https://docs.rs/memory_addr)
[![CI](https://github.com/arceos-org/memory_addr/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/arceos-org/memory_addr/actions/workflows/ci.yml)
Structures, functions and traits for physical and virtual memory addresses as well as memory mappings.

Wrappers and helper functions for physical and virtual memory addresses.
See documentations and readmes of the sub-crates for more information.

## Examples
- `memory_addr`([docs](https://docs.rs/memory_addr)|[crates.io](https://crates.io/crates/memory_addr)|[readme](memory_addr/README.md)): Wrappers and helper functions for physical and virtual memory addresses.
- `memory_set`([docs](https://docs.rs/memory_set)|[crates.io](https://crates.io/crates/memory_set)|[readme](memory_set/README.md)): Data structures and operations for managing memory mappings.

```rust
use memory_addr::{pa, va, va_range, PhysAddr, VirtAddr, MemoryAddr};

let phys_addr = PhysAddr::from(0x12345678);
let virt_addr = VirtAddr::from(0x87654321);

assert_eq!(phys_addr.align_down(0x1000usize), pa!(0x12345000));
assert_eq!(phys_addr.align_offset_4k(), 0x678);
assert_eq!(virt_addr.align_up_4k(), va!(0x87655000));
assert!(!virt_addr.is_aligned_4k());
assert!(va!(0xabcedf0).is_aligned(16usize));

let va_range = va_range!(0x87654000..0x87655000);
assert_eq!(va_range.start, va!(0x87654000));
assert_eq!(va_range.size(), 0x1000);
assert!(va_range.contains(virt_addr));
assert!(va_range.contains_range(va_range!(virt_addr..virt_addr + 0x100)));
assert!(!va_range.contains_range(va_range!(virt_addr..virt_addr + 0x1000)));
```
15 changes: 15 additions & 0 deletions memory_addr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "memory_addr"
description = "Wrappers and helper functions for physical and virtual addresses"
documentation = "https://docs.rs/memory_addr"
keywords = ["arceos", "address", "virtual-memory"]

version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
categories.workspace = true

[dependencies]
29 changes: 29 additions & 0 deletions memory_addr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# memory_addr

[![Crates.io](https://img.shields.io/crates/v/memory_addr)](https://crates.io/crates/memory_addr)
[![Docs.rs](https://docs.rs/memory_addr/badge.svg)](https://docs.rs/memory_addr)
[![CI](https://github.com/arceos-org/memory_addr/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/arceos-org/memory_addr/actions/workflows/ci.yml)

Wrappers and helper functions for physical and virtual memory addresses.

## Examples

```rust
use memory_addr::{pa, va, va_range, PhysAddr, VirtAddr, MemoryAddr};

let phys_addr = PhysAddr::from(0x12345678);
let virt_addr = VirtAddr::from(0x87654321);

assert_eq!(phys_addr.align_down(0x1000usize), pa!(0x12345000));
assert_eq!(phys_addr.align_offset_4k(), 0x678);
assert_eq!(virt_addr.align_up_4k(), va!(0x87655000));
assert!(!virt_addr.is_aligned_4k());
assert!(va!(0xabcedf0).is_aligned(16usize));

let va_range = va_range!(0x87654000..0x87655000);
assert_eq!(va_range.start, va!(0x87654000));
assert_eq!(va_range.size(), 0x1000);
assert!(va_range.contains(virt_addr));
assert!(va_range.contains_range(va_range!(virt_addr..virt_addr + 0x100)));
assert!(!va_range.contains_range(va_range!(virt_addr..virt_addr + 0x1000)));
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions memory_set/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "memory_set"
description = "Data structures and operations for managing memory mappings"
documentation = "https://docs.rs/memory_set"
keywords = ["arceos", "virtual-memory", "memory-area", "mmap"]

version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
categories.workspace = true

[dependencies]
memory_addr = "0.2"
# todo: update it to local one once it gets adapted to the current version
# memory_addr = { path = "../memory_addr", version = "0.2" }
86 changes: 86 additions & 0 deletions memory_set/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# memory_set

[![Crates.io](https://img.shields.io/crates/v/memory_set)](https://crates.io/crates/memory_set)
[![Docs.rs](https://docs.rs/memory_set/badge.svg)](https://docs.rs/memory_set)
[![CI](https://github.com/arceos-org/memory_addr/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/arceos-org/memory_addr/actions/workflows/ci.yml)

Data structures and operations for managing memory mappings.

It is useful to implement [`mmap`][1], [`munmap`][1] and [`mprotect`][2].

[1]: https://man7.org/linux/man-pages/man2/mmap.2.html
[2]: https://man7.org/linux/man-pages/man2/mprotect.2.html

## Examples

```rust
use memory_addr::{va, va_range, VirtAddr};
use memory_set::{MappingBackend, MemoryArea, MemorySet};

const MAX_ADDR: usize = 0x10000;

/// A mock memory flags.
type MockFlags = u8;
/// A mock page table, which is a simple array that maps addresses to flags.
type MockPageTable = [MockFlags; MAX_ADDR];

/// A mock mapping backend that manipulates the page table on `map` and `unmap`.
#[derive(Clone)]
struct MockBackend;

let mut pt = [0; MAX_ADDR];
let mut memory_set = MemorySet::<MockFlags, MockPageTable, MockBackend>::new();

// Map [0x1000..0x5000).
memory_set.map(
/* area: */ MemoryArea::new(va!(0x1000), 0x4000, 1, MockBackend),
/* page_table: */ &mut pt,
/* unmap_overlap */ false,
).unwrap();
// Unmap [0x2000..0x4000), will split the area into two parts.
memory_set.unmap(va!(0x2000), 0x2000, &mut pt).unwrap();

let areas = memory_set.iter().collect::<Vec<_>>();
assert_eq!(areas.len(), 2);
assert_eq!(areas[0].va_range(), va_range!(0x1000..0x2000));
assert_eq!(areas[1].va_range(), va_range!(0x4000..0x5000));

// Underlying operations to do when manipulating mappings.
impl MappingBackend<MockFlags, MockPageTable> for MockBackend {
fn map(&self, start: VirtAddr, size: usize, flags: MockFlags, pt: &mut MockPageTable) -> bool {
for entry in pt.iter_mut().skip(start.as_usize()).take(size) {
if *entry != 0 {
return false;
}
*entry = flags;
}
true
}

fn unmap(&self, start: VirtAddr, size: usize, pt: &mut MockPageTable) -> bool {
for entry in pt.iter_mut().skip(start.as_usize()).take(size) {
if *entry == 0 {
return false;
}
*entry = 0;
}
true
}

fn protect(
&self,
start: VirtAddr,
size: usize,
new_flags: MockFlags,
pt: &mut MockPageTable,
) -> bool {
for entry in pt.iter_mut().skip(start.as_usize()).take(size) {
if *entry == 0 {
return false;
}
*entry = new_flags;
}
true
}
}
```
Loading

0 comments on commit 41b0864

Please sign in to comment.