1The SeaBIOS code is required to support multiple x86 CPU memory 2models. This requirement impacts the code layout and internal storage 3of SeaBIOS. 4 5x86 Memory Models 6================= 7 8The x86 line of CPUs has evolved over many years. The original 8086 9chip used 16bit pointers and could only address 1 megabyte of memory. 10The 80286 CPU still used 16bit pointers, but could address up to 16 11megabytes of memory. The 80386 chips could process 32bit instructions 12and could access up to 4 gigabyte of memory. The most recent x86 chips 13can process 64bit instructions and access 16 exabytes of ram. 14 15During the evolution of the x86 CPUs from the 8086 to the 80386 the 16BIOS was extended to handle calls in the various modes that the CPU 17implemented. 18 19This section outlines the five different x86 CPU execution and memory 20access models that SeaBIOS supports. 21 2216bit real mode 23--------------- 24 25This mode is a 26[segmented](http://en.wikipedia.org/wiki/Memory_segmentation) memory 27mode invoked by callers. The CPU defaults to executing 16bit 28instructions. Callers typically invoke the BIOS by issuing an "int x" 29instruction which causes a software 30[interrupt](http://en.wikipedia.org/wiki/Interrupt) that is handled by 31the BIOS. The SeaBIOS code also handles hardware interrupts in this 32mode. SeaBIOS can only access the first 1 megabyte of memory in this 33mode, but it can access any part of that first megabyte. 34 3516bit bigreal mode 36------------------ 37 38This mode is a segmented memory mode that is used for [option 39roms](http://en.wikipedia.org/wiki/Option_ROM). The CPU defaults to 40executing 16bit instructions and segmented memory accesses are still 41used. However, the segment limits are increased so that the entire 42first 4 gigabytes of memory is fully accessible. Callers can invoke 43all the [16bit real mode](#16bit_real_mode) functions while in this 44mode and can also invoke the Post Memory Manager (PMM) functions that 45are available during option rom execution. 46 4716bit protected mode 48-------------------- 49 50CPU execution in this mode is similar to [16bit real 51mode](#16bit_real_mode). The CPU defaults to executing 16bit 52instructions. However, each segment register indexes a "descriptor 53table", and it is difficult or impossible to know what the physical 54address of each segment is. Generally speaking, the BIOS can only 55access code and data in the f-segment. The PCIBIOS, APM BIOS, and PNP 56BIOS all have documented 16bit protected mode entry points. 57 58Some old code may attempt to invoke the standard [16bit real 59mode](#16bit_real_mode) entry points while in 16bit protected 60mode. The PCI BIOS specification explicitly requires that the legacy 61"int 1a" real mode entry point support 16bit protected mode calls if 62they are for the PCI BIOS. Callers of other legacy entry points in 63protected mode have not been observed and SeaBIOS does not support 64them. 65 6632bit segmented mode 67-------------------- 68 69In this mode the processor runs in 32bit mode, but the segment 70registers may have a limit and may have a non-zero offset. In effect, 71this mode has all of the limitations of [16bit protected 72mode](#16bit_protected_mode) - the main difference between the modes 73is that the processor defaults to executing 32bit instructions. In 74addition to these limitations, callers may also run the SeaBIOS code 75at varying virtual addresses and so the code must support code 76relocation. The PCI BIOS specification and APM BIOS specification 77define 32bit segmented mode interfaces. 78 7932bit flat mode 80--------------- 81 82In this mode the processor defaults to executing 32bit instructions, 83and all segment registers have an offset of zero and allow access to 84the entire first 4 gigabytes of memory. This is the only "sane" mode 85for 32bit code - modern compilers and modern operating systems will 86generally only support this mode (when running 32bit code). 87Ironically, it's the only mode that is not strictly required for a 88BIOS to support. SeaBIOS uses this mode internally to support the POST 89and BOOT [phases of execution](Execution and code flow). 90 91code16gcc 92========= 93 94In order to produce code that can run when the processor is in a 16bit 95mode, SeaBIOS uses the 96[binutils](http://en.wikipedia.org/wiki/GNU_Binutils) ".code16gcc" 97assembler flag. This instructs the assembler to emit extra prefix 98opcodes so that the 32bit code produced by 99[gcc](http://en.wikipedia.org/wiki/GNU_Compiler_Collection) will run 100even when the processor is in 16bit mode. Note that gcc always 101produces 32bit code - it does not know about the ".code16gcc" flag and 102does not know that the code will run in a 16bit mode. 103 104SeaBIOS uses the same code for all of the 16bit modes ([16bit real 105mode](#16bit_real_mode), [16bit bigreal mode](#16bit_bigreal_mode), 106and [16bit protected mode](#16bit_protected_mode)) and that code is 107assembled using ".code16gcc". SeaBIOS is careful to use segment 108registers properly so that the same code can run in the different 10916bit modes that it needs to support. 110 111C code mode flags 112================= 113 114Two compile time flags are available to determine the memory model the 115code is intended for: MODE16 and MODESEGMENT. When compiling for the 11616 bit modes, MODE16 is true and MODESEGMENT is true. In 32bit 117segmented mode, MODE16 is false and MODESEGMENT is true. In 32bit flat 118mode both MODE16 and MODESEGMENT are false. 119 120Common memory used at run-time 121============================== 122 123There are several memory areas that the SeaBIOS "runtime" 124[phase](Execution and code flow) makes use of: 125 126* 0x000000-0x000400: Interrupt descriptor table (IDT). This area 127 defines 256 interrupt vectors as defined by the Intel CPU 128 specification for 16bit irq handlers. This area is read/writable at 129 runtime and can be accessed from 16bit real mode and 16bit bigreal 130 mode calls. SeaBIOS only uses this area to maintain compatibility 131 with legacy systems. 132 133* 0x000400-0x000500: BIOS Data Area (BDA). This area contains various 134 legacy flags and attributes. The area is read/writable at runtime 135 and can be accessed from 16bit real mode and 16bit bigreal mode 136 calls. SeaBIOS only uses this area to maintain compatibility with 137 legacy systems. 138 139* 0x09FC00-0x0A0000 (typical): Extended BIOS Data Area (EBDA). This 140 area contains a few legacy flags and attributes. The area is 141 typically located at 0x9FC00, but it can be moved by option roms, by 142 legacy operating systems, and by SeaBIOS if 143 CONFIG_MALLOC_UPPERMEMORY is not set. Its actual location is 144 determined by a pointer in the BDA. The area is read/writable at 145 runtime and can be accessed from 16bit real mode and 16bit bigreal 146 mode calls. SeaBIOS only uses this area to maintain compatibility 147 with legacy systems. 148 149* 0x0E0000-0x0F0000 (typical): "low" memory. This area is used for 150 custom read/writable storage internal to SeaBIOS. The area is 151 read/writable at runtime and can be accessed from 16bit real mode 152 and 16bit bigreal mode calls. The area is typically located at the 153 end of the e-segment, but the build may position it anywhere in the 154 0x0C0000-0x0F0000 region. However, if CONFIG_MALLOC_UPPERMEMORY is 155 not set, then this region is between 0x090000-0x0A0000. Space is 156 allocated in this region by either marking a global variable with 157 the "VARLOW" flag or by calling malloc_low() during 158 initialization. The area can be grown dynamically (via malloc_low), 159 but it will never exceed 64K. 160 161* 0x0F0000-0x100000: The BIOS segment. This area is used for both 162 runtime code and static variables. Space is allocated in this region 163 by either marking a global variable with VAR16, one of the VARFSEG 164 flags, or by calling malloc_fseg() during initialization. The area 165 is read-only at runtime and can be accessed from 16bit real mode, 166 16bit bigreal mode, 16bit protected mode, and 32bit segmented mode 167 calls. 168 169All of the above areas are also read/writable during the SeaBIOS 170initialization phase and are accessible when in 32bit flat mode. 171 172Segmented mode memory access 173============================ 174 175The assembler entry functions for segmented mode calls (all modes 176except [32bit flat mode](#32bit_flat_mode)) will arrange 177to set the data segment (%ds) to be the same as the stack segment 178(%ss) before calling any C code. This permits all C variables located 179on the stack and C pointers to data located on the stack to work as 180normal. 181 182However, all code running in segmented mode must wrap non-stack memory 183accesses in special macros. These macros ensure the correct segment 184register is used. Failure to use the correct macro will result in an 185incorrect memory access that will likely cause hard to find errors. 186 187There are three low-level memory access macros: 188 189* GET_VAR / SET_VAR : Accesses a variable using the specified segment 190 register. This isn't typically used directly by C code. 191 192* GET_FARVAR / SET_FARVAR : Assigns the extra segment (%es) to the 193 given segment id and then performs the given memory access via %es. 194 195* GET_FLATPTR / SET_FLATPTR : These macros take a 32bit pointer, 196 construct a segment/offset pair valid in real mode, and then perform 197 the given access. These macros must not be used in 16bit protected 198 mode or 32bit segmented mode. 199 200Since most memory accesses are to [common memory used at 201run-time](#Common_memory_used_at_run-time), several helper 202macros are also available. 203 204* GET_IDT / SET_IDT : Access the interrupt descriptor table (IDT). 205 206* GET_BDA / SET_BDA : Access the BIOS Data Area (BDA). 207 208* GET_EBDA / SET_EBDA : Access the Extended BIOS Data Area (EBDA). 209 210* GET_LOW / SET_LOW : Access internal variables marked with 211 VARLOW. (There are also related macros GET_LOWFLAT / SET_LOWFLAT for 212 accessing storage allocated with malloc_low.) 213 214* GET_GLOBAL : Access internal variables marked with the VAR16 or 215 VARFSEG flags. (There is also the related macro GET_GLOBALFLAT for 216 accessing storage allocated with malloc_fseg.) 217 218Memory available during initialization 219====================================== 220 221During the POST [phase](Execution and code flow) the code 222can fully access the first 4 gigabytes of memory. However, memory 223accesses are generally limited to the [common memory used at 224run-time](#Common_memory_used_at_run-time) and areas 225allocated at runtime via one of the malloc calls: 226 227* malloc_high : Permanent high-memory zone. This area is used for 228 custom read/writable storage internal to SeaBIOS. The area is 229 located at the top of the first 4 gigabytes of ram. It is commonly 230 used for storing standard tables accessed by the operating system at 231 runtime (ACPI, SMBIOS, and MPTable) and for DMA buffers used by 232 hardware drivers. The area is read/writable at runtime and an entry 233 in the e820 memory map is used to reserve it. When running on an 234 emulator that has only 1 megabyte of ram this zone will be empty. 235 236* malloc_tmphigh : Temporary high-memory zone. This area is used for 237 custom read/writable storage during the SeaBIOS initialization 238 phase. The area generally starts after the first 1 megabyte of ram 239 (0x100000) and ends prior to the Permanent high-memory zone. When 240 running on an emulator that has only 1 megabyte of ram this zone 241 will be empty. The area is not reserved from the operating system, 242 so it must not be accessed after the SeaBIOS initialization phase. 243 244* malloc_tmplow : Temporary low-memory zone. This area is used for 245 custom read/writable storage during the SeaBIOS initialization 246 phase. The area resides between 0x07000-0x90000. The area is not 247 reserved from the operating system and by specification it is 248 required to be zero'd at the end of the initialization phase. 249 250The "tmplow" and "tmphigh" regions are only available during the 251initialization phase. Any access (either read or write) after 252completion of the initialization phase can result in difficult to find 253errors. 254