docs: document startup sequence, including boot arguments
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
85
memory.md
85
memory.md
@ -1,6 +1,20 @@
|
||||
# Memory Management
|
||||
|
||||
In general, memory cannot be mapped to more than one process. This includes RAM, storage, and io peripherals.
|
||||
# Memory Layout
|
||||
|
||||
Xous assumes a memory-mapped IO system. Furthermore, it assumes there
|
||||
is one section of "general-purpose RAM", and zero or more additional
|
||||
memory sections.
|
||||
|
||||
Memory is divided into "pages" of 4096 bytes, and are allocated based on
|
||||
this number. It is considered an error to request memory that isn't
|
||||
aligned to this address, and it is an error to request a multiple of pages
|
||||
that is different from this number. For example, you cannot request 4097
|
||||
bytes -- you must request 8192 bytes.
|
||||
|
||||
Memory is allocated on a first-come, first-served basis. Physical addresses
|
||||
may be specified when allocating memory, in which case they are taken from
|
||||
that physical address. Otherwise, they are pulled from the "general-purpose
|
||||
RAM" section.
|
||||
|
||||
A process can request specific memory ranges to be allocated. For example, a `uart_server` might request the UART memory region be allocated so that it can handle that device and provide a service. This region cannot be re-mapped to another process until it is freed.
|
||||
|
||||
@ -8,6 +22,16 @@ A process can request more memory for its heap. This will pull memory from the
|
||||
|
||||
If a process intends to spawn multiple threads, then it must malloc that memory prior to creating the thread.
|
||||
|
||||
## Special Virtual Memory Addresses
|
||||
|
||||
These addresses are statically mapped in virtual memory. They are only visible in "Supervisor" mode. However, they are globally mapped, and are available in every process.
|
||||
|
||||
| Address | Description
|
||||
| ---------- | -----------
|
||||
| 0x01000000 | Kernel arguments, allocation tables
|
||||
| 0x02000000 | Kernel binary image
|
||||
| 0x04000000 | Kernel data section
|
||||
|
||||
## Memory Whitelist
|
||||
|
||||
Memory is kept in a whitelist. That is, when calling `sys_memory_allocate()`, the address is first validated against a list of known ranges. This has two major benefits:
|
||||
@ -20,3 +44,60 @@ Memory is kept in a whitelist. That is, when calling `sys_memory_allocate()`, t
|
||||
Each valid memory page has an associated table entry. This entry simply contains a `XousPid`, to indicate which process the memory block belongs to. A `XousPid` of `0` is invalid, and indicates the region is free. A `XousPid` of `1` indicates the page belongs to the kernel.
|
||||
|
||||
In a system with ample amounts of memory, all valid memory page would get its own memory table. However, in resource-constrained systems, a simple array is not suitable, and so a programmatic lookup table is used instead.
|
||||
|
||||
## Kernel Arguments
|
||||
|
||||
There are several arguments that specify where kernel structures should go.
|
||||
|
||||
### Memory Blocks
|
||||
|
||||
The kernel needs to know the range of pages. This is passed to the kernel
|
||||
as a list in the following form:
|
||||
|
||||
```
|
||||
MBLK,$count,
|
||||
$start1,$len1,$name
|
||||
$start2,$len2,$name
|
||||
...
|
||||
```
|
||||
|
||||
The first memory range that is listed is always RAM, which is the range that will be used for dealing with `sbrk` and unspecified memory allocations. The name should be printable ASCII, and is primarily used for debugging.
|
||||
|
||||
### Kernel Memory
|
||||
|
||||
This structure specifies how kernel memory is laid out.
|
||||
|
||||
## Allocation Tables
|
||||
|
||||
Each page of memory has an entry in the allocation tables. When allocating
|
||||
a new page, Xous ensures that page is not currently allocated to another
|
||||
process. This ensures that each page of memory is only assigned to one
|
||||
process at a time, unless that page is handed out as shared.
|
||||
|
||||
Allocation tables have the following layout:
|
||||
|
||||
```rust
|
||||
struct AllocationEntry {
|
||||
/// PID that owns this page. `0` if this
|
||||
/// page is unallocated.
|
||||
pid: XousPid,
|
||||
}
|
||||
|
||||
struct PageRange {
|
||||
/// A slice of all allocations within this range.
|
||||
entries: &[AllocationEntry],
|
||||
}
|
||||
|
||||
struct PageAllocations {
|
||||
/// Each range of memory gets its own allocation table.
|
||||
/// ranges[0] is always defined as RAM,
|
||||
/// and is where memory comes from when
|
||||
/// no physical address is specified.
|
||||
ranges: &[PageRange],
|
||||
}
|
||||
```
|
||||
|
||||
## Page Tables
|
||||
|
||||
Each process requires its own page table. The kernel will be mapped to a fixed offset in each process, in order to save some RAM and make
|
||||
context switches easier.
|
||||
|
Reference in New Issue
Block a user