From e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb Mon Sep 17 00:00:00 2001 From: Yang Zhang Date: Fri, 28 Aug 2015 09:58:54 +0800 Subject: Add qemu 2.4.0 Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang --- qemu/roms/seabios/docs/Execution_and_code_flow.md | 178 ++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 qemu/roms/seabios/docs/Execution_and_code_flow.md (limited to 'qemu/roms/seabios/docs/Execution_and_code_flow.md') diff --git a/qemu/roms/seabios/docs/Execution_and_code_flow.md b/qemu/roms/seabios/docs/Execution_and_code_flow.md new file mode 100644 index 000000000..9396ecaa4 --- /dev/null +++ b/qemu/roms/seabios/docs/Execution_and_code_flow.md @@ -0,0 +1,178 @@ +This page provides a high-level description of some of the major code +phases that SeaBIOS transitions through and general information on +overall code flow. + +SeaBIOS code phases +=================== + +The SeaBIOS code goes through a few distinct code phases during its +execution lifecycle. Understanding these code phases can help when +reading and enhancing the code. + +POST phase +---------- + +The Power On Self Test (POST) phase is the initialization phase of the +BIOS. This phase is entered when SeaBIOS first starts execution. The +goal of the phase is to initialize internal state, initialize external +interfaces, detect and setup hardware, and to then start the boot +phase. + +On emulators, this phase starts when the CPU starts execution in 16bit +mode at 0xFFFF0000:FFF0. The emulators map the SeaBIOS binary to this +address, and SeaBIOS arranges for romlayout.S:reset_vector() to be +present there. This code calls romlayout.S:entry_post() which then +calls post.c:handle_post() in 32bit mode. + +On coreboot, the build arranges for romlayout.S:entry_elf() to be +called in 32bit mode. This then calls post.c:handle_post(). + +On CSM, the build arranges for romlayout.S:entry_csm() to be called +(in 16bit mode). This then calls csm.c:handle_csm() in 32bit mode. +Unlike on the emulators and coreboot, the SeaBIOS CSM POST phase is +orchastrated with UEFI and there are several calls back and forth +between SeaBIOS and UEFI via handle_csm() throughout the POST +process. + +The POST phase itself has several sub-phases. + +* The "preinit" sub-phase: code run prior to code relocation. +* The "init" sub-phase: code to initialize internal variables and + interfaces. +* The "setup" sub-phase: code to setup hardware and drivers. +* The "prepboot" sub-phase: code to finalize interfaces and prepare + for the boot phase. + +At completion of the POST phase, SeaBIOS invokes an "int 0x19" +software interrupt in 16bit mode which begins the boot phase. + +Boot phase +---------- + +The goal of the boot phase is to load the first portion of the +operating system's boot loader into memory and start execution of that +boot loader. This phase starts when a software interrupt ("int 0x19" +or "int 0x18") is invoked. The code flow starts in 16bit mode in +romlayout.S:entry_19() or romlayout.S:entry_18() which then +transition to 32bit mode and call boot.c:handle_19() or +boot.c:handle_18(). + +The boot phase is technically also part of the "runtime" phase of +SeaBIOS. It is typically invoked immiediately after the POST phase, +but it can also be invoked by an operating system or be invoked +multiple times in an attempt to find a valid boot media. Although the +boot phase C code runs in 32bit mode it does not have write access to +the 0x0f0000-0x100000 memory region and can not call the various +malloc_X() calls. See [Memory Model](Memory Model) for +more information. + +Main runtime phase +------------------ + +The main runtime phase occurs after the boot phase starts the +operating system. Once in this phase, the SeaBIOS code may be invoked +by the operating system using various 16bit and 32bit calls. The goal +of this phase is to support these legacy calling interfaces and to +provide compatibility with BIOS standards. There are multiple entry +points for the BIOS - see the entry_XXX() assembler functions in +romlayout.S. + +Callers use most of these legacy entry points by setting up a +particular CPU register state, invoking the BIOS, and then inspecting +the returned CPU register state. To handle this, SeaBIOS will backup +the current register state into a "struct bregs" (see romlayout.S, +entryfuncs.S, and bregs.h) on call entry and then pass this struct to +the C code. The C code can then inspect the register state and modify +it. The assembler entry functions will then restore the (possibly +modified) register state from the "struct bregs" on return to the +caller. + +Resume and reboot +----------------- + +As noted above, on emulators SeaBIOS handles the 0xFFFF0000:FFF0 +machine startup execution vector. This vector is also called on +machine faults and on some machine "resume" events. It can also be +called (as 0xF0000:FFF0) by software as a request to reboot the +machine (on emulators, coreboot, and CSM). + +The SeaBIOS "resume and reboot" code handles these calls and attempts +to determine the desired action of the caller. Code flow starts in +16bit mode in romlayout.S:reset_vector() which calls +romlayout.S:entry_post() which calls romlayout.S:entry_resume() which +calls resume.c:handle_resume(). Depending on the request the +handle_resume() code may transition to 32bit mode. + +Technically this code is part of the "runtime" phase, so even though +parts of it run in 32bit mode it still has the same limitations of the +runtime phase. + +Threads +======= + +Internally SeaBIOS implements a simple cooperative multi-tasking +system. The system works by giving each "thread" its own stack, and +the system round-robins between these stacks whenever a thread issues +a yield() call. This "threading" system may be more appropriately +described as [coroutines](http://en.wikipedia.org/wiki/Coroutine). +These "threads" do not run on multiple CPUs and are not preempted, so +atomic memory accesses and complex locking is not required. + +The goal of these threads is to reduce overall boot time by +parallelizing hardware delays. (For example, by allowing the wait for +an ATA harddrive to spinup and respond to commands to occur in +parallel with the wait for a PS/2 keyboard to respond to a setup +command.) These hardware setup threads are only available during the +"setup" sub-phase of the [POST phase](#POST_phase). + +The code that implements threads is in stacks.c. + +Hardware interrupts +=================== + +The SeaBIOS C code always runs with hardware interrupts disabled. All +of the C code entry points (see romlayout.S) are careful to explicitly +disable hardware interrupts (via "cli"). Because running with +interrupts disabled increases interrupt latency, any C code that could +loop for a significant amount of time (more than about 1 ms) should +periodically call yield(). The yield() call will briefly enable +hardware interrupts to occur, then disable interrupts, and then resume +execution of the C code. + +There are two main reasons why SeaBIOS always runs C code with +interrupts disabled. The first reason is that external software may +override the default SeaBIOS handlers that are called on a hardware +interrupt event. Indeed, it is common for DOS based applications to do +this. These legacy third party interrupt handlers may have +undocumented expections (such as stack location and stack size) and +may attempt to call back into the various SeaBIOS software services. +Greater compatibility and more reproducible results can be achieved by +only permitting hardware interrupts at specific points (via yield() +calls). The second reason is that much of SeaBIOS runs in 32bit mode. +Attempting to handle interrupts in both 16bit mode and 32bit mode and +switching between modes to delegate those interrupts is an unneeded +complexity. Although disabling interrupts can increase interrupt +latency, this only impacts legacy systems where the small increase in +interrupt latency is unlikely to be noticeable. + +Extra 16bit stack +================= + +SeaBIOS implements 16bit real mode handlers for both hardware +interrupts and software request "interrupts". In a traditional BIOS, +these requests would use the caller's stack space. However, the +minimum amount of space the caller must provide has not been +standardized and very old DOS programs have been observed to allocate +very small amounts of stack space (100 bytes or less). + +By default, SeaBIOS now switches to its own stack on most 16bit real +mode entry points. This extra stack space is allocated in ["low +memory"](Memory Model). It ensures SeaBIOS uses a minimal amount of a +callers stack (typically no more than 16 bytes) for these legacy +calls. (More recently defined BIOS interfaces such as those that +support 16bit protected and 32bit protected mode calls standardize a +minimum stack size with adequete space, and SeaBIOS generally will not +use its extra stack in these cases.) + +The code to implement this stack "hopping" is in romlayout.S and in +stacks.c. -- cgit 1.2.3-korg