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 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
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.