ZealOS/docs/Doc/MemoryOverview.DD.html
2021-12-11 06:10:58 -05:00

121 lines
13 KiB
HTML
Executable file

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<meta name="generator" content="ZealOS V1.07">
<style type="text/css">
body {background-color:#1f1f1f;}
.cF0{color:#e3e3e3;background-color:#1f1f1f;}
.cF1{color:#4f84a6;background-color:#1f1f1f;}
.cF2{color:#73a255;background-color:#1f1f1f;}
.cF3{color:#297582;background-color:#1f1f1f;}
.cF4{color:#b34f4b;background-color:#1f1f1f;}
.cF5{color:#8a52c3;background-color:#1f1f1f;}
.cF6{color:#b7822f;background-color:#1f1f1f;}
.cF7{color:#444444;background-color:#1f1f1f;}
.cF8{color:#6d6d6d;background-color:#1f1f1f;}
.cF9{color:#94bfde;background-color:#1f1f1f;}
.cFA{color:#a1ce97;background-color:#1f1f1f;}
.cFB{color:#6db4be;background-color:#1f1f1f;}
.cFC{color:#e88e88;background-color:#1f1f1f;}
.cFD{color:#ca94e8;background-color:#1f1f1f;}
.cFE{color:#d4b475;background-color:#1f1f1f;}
.cFF{color:#1f1f1f;background-color:#1f1f1f;}
</style>
</head>
<body>
<pre style="font-family:monospace;font-size:12pt">
<a name="l1"></a><span class=cF5> Memory Overview</span><span class=cF0>
<a name="l2"></a>
<a name="l3"></a>Paging is practically not used. 64-bit mode requires paging, however, so it is identity-mapped -- virtual identical to
<a name="l4"></a>physical. All tasks on all cores use the same page table map, just as though all addresses are physical addresses. 2Meg or
<a name="l5"></a>1Gig page table entries are used. Nothing swaps to disk.
<a name="l6"></a>
<a name="l7"></a>In ZealOS, the lowest 2Gig of memory is called the </span><span class=cF2>code heap</span><span class=cF0>. ZealOS's compiler always uses 32-bit signed relative JMP &amp; CALL
<a name="l8"></a>insts because 64-bit CALLs take two insts. With signed +/- 32-bit values, code can only call a function within 2Gig distance.
<a name="l9"></a> Therefore, ZealOS keeps all code in the lowest 2Gig memory addresses including what would normally be called &quot;the kernel&quot;.
<a name="l10"></a>Two Gig is plenty for code, don't worry.
<a name="l11"></a>
<a name="l12"></a>You can create new, independent heaps using </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/HeapCtrl.ZC.html#l1"><span class=cF4>HeapCtrlInit</span></a><span class=cF0>(). Then, use the </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l3560"><span class=cF4>CHeapCtrl</span></a><span class=cF0> as the 2nd arg to </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.ZC.html#l391"><span class=cF4>MAlloc</span></a><span class=cF0>(). See </span><a href="https://zeal-operating-system.github.io/ZealOS/System/Utils/HeapLog.ZC.html#l83"><span class=cF4>HeapLog</span></a><span class=cF0>()
<a name="l13"></a>for an example.
<a name="l14"></a>
<a name="l15"></a>Memory alloced by a task will be freed when the task is killed. The </span><a href="https://zeal-operating-system.github.io/ZealOS/Doc/Glossary.DD.html#l154"><span class=cF4>System Task</span></a><span class=cF0> is a task that never dies. Its memory is like
<a name="l16"></a>kernel memory in other operating systems. See </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.ZC.html#l408"><span class=cF4>SysCAlloc</span></a><span class=cF0>(), </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.ZC.html#l394"><span class=cF4>SysMAlloc</span></a><span class=cF0>(), </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.ZC.html#l427"><span class=cF4>SysMAllocIdent</span></a><span class=cF0>() and </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.ZC.html#l503"><span class=cF4>SysStrNew</span></a><span class=cF0>().
<a name="l17"></a>
<a name="l18"></a>All of the regular page tables are marked, &quot;cached&quot;. When accessing hardware, however, you need uncached page table. The
<a name="l19"></a>lowest 4Gig addresses have an alias to access hardware located toward the top of mapped space, </span><span class=cF2>0x01D7800000</span><span class=cF0>. See </span><span class=cF4>
<a name="l20"></a></span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/MultiProc.ZC.html#l152"><span class=cF4>dev.uncached_alias</span></a><span class=cF0>.
<a name="l21"></a>
<a name="l22"></a>During an extended powered-on session of ZealOS, in theory, memory will become fragmented, requiring a reboot. It has never
<a name="l23"></a>happens to me.
<a name="l24"></a>
<a name="l25"></a>See </span><a href="https://zeal-operating-system.github.io/ZealOS/System/Utils/MemRep.ZC.html#l219"><span class=cF4>MemRep</span></a><span class=cF0>() and </span><a href="https://zeal-operating-system.github.io/ZealOS/Demo/MemDemo.ZC.html#l1"><span class=cF4>::/Demo/MemDemo.ZC</span></a><span class=cF0>.
<a name="l26"></a>
<a name="l27"></a>
<a name="l28"></a></span><span class=cF5> Single System-wide Memory Map
<a name="l29"></a>
<a name="l30"></a></span><span class=cF2> 0x0000007C00- 0x00000371FF</span><span class=cF0>
<a name="l31"></a> Kernel module, placed here by the boot-loader, </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l4477"><span class=cF4>BOOT_RAM_BASE</span></a><span class=cF0>.
<a name="l32"></a>
<a name="l33"></a></span><span class=cF2> 0x0000096600- 0x0000096FFF</span><span class=cF0>
<a name="l34"></a> Boot block relocated here before loading the Kernel module, </span><a href="https://zeal-operating-system.github.io/ZealOS/System/Boot/BootDVD.ZC.html#l1"><span class=cF4>BootDVD</span></a><span class=cF0> &amp; </span><a href="https://zeal-operating-system.github.io/ZealOS/System/Boot/BootHD.ZC.html#l1"><span class=cF4>BootHD</span></a><span class=cF0>.
<a name="l35"></a>
<a name="l36"></a></span><span class=cF2> 0x0000097000- 0x000009703B</span><span class=cF0> Multicore start-up vect code, </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l665"><span class=cF4>MPN_VECT</span></a><span class=cF0>.
<a name="l37"></a></span><span class=cF2>~0x000009F000- 0x000009FFFF</span><span class=cF0> Extended BIOS data area.
<a name="l38"></a></span><span class=cF2> 0x00000A0000- 0x00000BFFFF</span><span class=cF0> VGA graphics mem with alias at </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/KGlobals.ZC.html#l30"><span class=cF4>text</span></a><span class=cF0>.vga_alias.
<a name="l39"></a></span><span class=cF2> 0x0000100000- 0x0000101FFF</span><span class=cF0> </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l4120"><span class=cF4>CSysFixedArea</span></a><span class=cF0> for misc.
<a name="l40"></a></span><span class=cF2> 0x0000110000- 0x007FFFFFFF</span><span class=cF0> Code Heap mem.
<a name="l41"></a>
<a name="l42"></a></span><span class=cF2> 0x00E0000000- 0x00FFFFFFFF</span><span class=cF0>
<a name="l43"></a> 32-bit devices could alloc memory at 0xF0000000 going up, but this is wrong, since some PCs already have devices at
<a name="l44"></a> 0xF0000000. PCI devices are supported, so </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MemPhysical.ZC.html#l64"><span class=cF4>Mem32DevAlloc</span></a><span class=cF0>() flaws could become an issue.
<a name="l45"></a>
<a name="l46"></a></span><span class=cF2> 0x0080000000-~0x00DFFFFFFF</span><span class=cF0>
<a name="l47"></a></span><span class=cF2> 0x0100000000-~0x01D77FFFFF</span><span class=cF0>
<a name="l48"></a> Data Heap mem. (The physical memory that exists in this range is data heap.)
<a name="l49"></a>
<a name="l50"></a></span><span class=cF2> 0x01D7800000- 0x02D77FFFFF</span><span class=cF0>
<a name="l51"></a> Uncached alias of first 4Gig. (For 32-bit device access.)
<a name="l52"></a>
<a name="l53"></a></span><span class=cF2> - 0x02D77FFFFF</span><span class=cF0>
<a name="l54"></a> 64-bit devices are alloced with </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MemPhysical.ZC.html#l122"><span class=cF4>Mem64DevAlloc</span></a><span class=cF0>() counting backward.
<a name="l55"></a>
<a name="l56"></a>
<a name="l57"></a>
<a name="l58"></a>* Note: There is a break in the data-heap block pool. This has no effect except the obvious effect that fragmentation has on
<a name="l59"></a>contiguous requests. You can </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.ZC.html#l391"><span class=cF4>MAlloc</span></a><span class=cF0>() an 8Gig chunk on a 12Gig machine. You can </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.ZC.html#l391"><span class=cF4>MAlloc</span></a><span class=cF0>() a 32Gig chunk on a 64Gig machine.
<a name="l60"></a>
<a name="l61"></a>* Note: For systems with less than 2Gig RAM, the code and data heap block pools are the same. For systems with 2-4Gig of RAM,
<a name="l62"></a>the code heap is 1/4 of the total. See </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/BlkPool.ZC.html#l31"><span class=cF4>BlkPoolsInit</span></a><span class=cF0>().
<a name="l63"></a>
<a name="l64"></a>
<a name="l65"></a></span><span class=cF5> History</span><span class=cF0>
<a name="l66"></a>
<a name="l67"></a>In 2003, Terry Davis wanted to make a no-paging ring-0-only 64-bit operating system for super speed with simplicity and full
<a name="l68"></a>access. With paging, every memory request requires 5 accesses -- it must access the address itself, 4K, 2Meg, 1Gig, and 512Gig
<a name="l69"></a>page tables, but the CPU's translation look-aside buffer mostly removes the penalty for using paging. So, he did not want to
<a name="l70"></a>use paging, but long mode requires it. He did the next best thing -- he identity-mapped everything and achieved the
<a name="l71"></a>simplicity he was after with subtle performance boosts, not wasting time changing address maps. We look forward to the day
<a name="l72"></a>Intel makes an optimized no-paging long mode.
<a name="l73"></a>
<a name="l74"></a>Terry needed VGA A0000-BFFFF memory to be write-through and 0xE0000000-0xFFFFFFFF to be uncached for various devices. All
<a name="l75"></a>64-bit computers allow stopping address translation at 2Meg page size, not using 4K. He wanted to use 2Meg for everything
<a name="l76"></a>because it's faster, with one less level of page tables. He had to make A0000-BFFFF write-through, though, so he could not
<a name="l77"></a>use 2Meg size on the lowest page. He did the lowest 2Meg area as 4K pages. He also unmapped the first 4K to cause a fault
<a name="l78"></a>when dereferencing NULL.
<a name="l79"></a>
<a name="l80"></a>In 2016, Terry came-up with an alternate idea. He double mapped the lowest memory with an alias that was uncached. Accessing
<a name="l81"></a>the lowest 2Meg area directly was cached but the alias he created up at the top of address space was uncached. See </span><span class=cF4>
<a name="l82"></a></span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MemPhysical.ZC.html#l157"><span class=cF4>UncachedAliasAlloc</span></a><span class=cF0>(). Unfortunately, he could no longer boast of the simplicity of identity mapping everything. Since many
<a name="l83"></a>of the users are familiar with A0000-BFFFF, it is actually pretty seriously unfortunate that they cannot use the
<a name="l84"></a>easy-to-understand numbers of A0000-BFFFF, but must access the relocated alias location. See </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/KMain.ZC.html#l113"><span class=cF4>text.vga_alias</span></a><span class=cF0>. We also no
<a name="l85"></a>longer cause a fault when dereferencing NULL.
<a name="l86"></a>
<a name="l87"></a>Then, Terry switched to 1Gig page sizes. For the lowest 4Gig, he set-up an alias up at the top of address space. See </span><span class=cF4>
<a name="l88"></a></span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MemPhysical.ZC.html#l157"><span class=cF4>UncachedAliasAlloc</span></a><span class=cF0>(). Not all computers support 1Gig page tables, however, so he also supported 2Meg.
<a name="l89"></a>
<a name="l90"></a>Terry's original plan was to allow changing the page tables as needed, so he had code for taking control of 2Meg pages and
<a name="l91"></a>marking them uncached or whatever. When he did an HDAudio driver, he requested some 32-bit address space as uncached. Today,
<a name="l92"></a>all of the first 4Gig can be accessed without caching at the </span><a href="https://zeal-operating-system.github.io/ZealOS/Kernel/MultiProc.ZC.html#l152"><span class=cF4>dev.uncached_alias</span></a><span class=cF0>.
</span></pre></body>
</html>