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