On Mon, Jun 14, 2010 at 10:21:43AM +0200, Stefan Reinauer wrote:
On 6/14/10 3:07 AM, Kevin O'Connor wrote:
The changes to ulzma wont work. The malloc_X calls only work in POST, however ulzma can be called during boot (when seabios boots a payload). As far as I can tell it shouldn't be necessary though. SeaBIOS has a 24K stack (at 0x7000) for the "main thread" during both post and boot (each "thread" only has a 4K stack, but no thread calls ulzma).
ulzma may take more than those 15kb, and the code is theoretically able to find out how much it needs... Is there a malloc that could be used here?
Unfortunately - no. Even if we implemented another way to grab memory, it could conflict with the location that the payload is deployed at (currently, the code assumes the payload wont be placed over the e/f segment or below 0x7000).
Is there some documentation on what each malloc version does? It's quite confusing for beginners :-)
Bah - real men use 10 different memory allocators!
There are 5 memory zones - tmplow, low, fseg, tmphigh, and high. Each of these has its own non-overlapping memory space. All allocations to these spaces are done through the pmm_malloc() call - but a number of wrappers (eg, malloc_tmphigh, memalign_high) are implemented to make the code more readable. The "pmm" in pmm_malloc stands for POST Memory Manager (a BIOS standard) - the call is only available during the POST phase of SeaBIOS.
The main reason for the different zones is to handle the different memory models that the BIOS must support (16 bit real mode, 16 bit "big real" mode, 16 bit protected mode, and 32 bit segmented mode). Each of these modes has restrictions on what and how memory can be accessed. Also, a further complication is that the BIOS standards call for some memory between 0xc0000-0x100000 to be marked as read-only after POST.
The tmplow zone is for allocations under 1Meg (available by real mode code) and is reserved only during the POST phase. This zone is actually zero'd at the end of POST.
The low zone is for allocations under 1Meg (available by real mode code) that is reserved after POST - the memory is no longer available for OS use. It's useful for scratch space needed by device drivers that support real-mode calls - the memory returned is read/writable even after POST.
The fseg zone is for allocations in the f-segment. This zone is useful for bios tables that need to be located in the f-segment. It is also useful for BIOS data (eg, drive descriptions) because the data can be reliably and efficiently accessed with the GET_GLOBALFLAT() macro (which is available in all calling modes). However, the f-segment is nominally made read-only at the end of POST, so it can't be used for variables needed at runtime.
The tmphigh zone is for allocations above 1Meg and is reserved only during the POST phase. Use of memory obtained here after POST is risky - it certainly can't be used by the BIOS after an OS starts.
The high zone is for allocations above 1Meg that are reserved from the OS. Currently, SeaBIOS places this zone at the very top of available 32bit memory. The memory is read/writable and available to device drivers. However, since no memory mode calling convention (except "big real" mode, which is unused after POST) supports access to this memory, it is really only useful for DMA scratch areas and for some BIOS tables.
Space from these zones (all except fseg) can also be allocated by option roms if they invoke the PMM interface.
There are a few other memory areas that don't have malloc calls - the bda (0-0x1000), the ebda, and the option rom space (0xc0000-0xf0000). The bda is rife with legacy programs assuming a certain layout, and so can't really be used for dynamic allocations. The ebda is very similar to the "low zone", but it can be relocated which makes it difficult to use (on the up side, it has a better chance of being available during 16bit protected mode calls). Finally, the option rom space is also very similar to the "low zone", but part of the space (those used by option roms) is nominally marked read-only after POST.
Anyway, this would probably make a good wiki page.