Differences

This shows you the differences between two versions of the page.

Link to this comparison view

dev:prefixdebugging [2009/10/17 03:33] (current)
stefanha created
Line 1: Line 1:
 +This page describes the boot prefixes and debugging tips.  Debugging a boot
 +prefix can be challenging because most code is assembly and it is not possible
 +to call into gPXE for utility and I/O functions.
  
 +===== How to identify a prefix issue =====
 +
 +A crash, hang, or other issue may be prefix-related if it occurs before gPXE
 +prints its banner. ​ If gPXE fails to load then it may be a prefix issue. ​ Odd
 +behavior when exiting gPXE may also be prefix issues.
 +
 +===== Overview =====
 +
 +The boot prefix is the first code executed when gPXE is started. ​ Its task is
 +to install gPXE into memory and set up the environment in which C code can run.
 +Prefix code is the only part of a gPXE image which is not compressed because it
 +contains the decompressor that is used to load the rest of gPXE.
 +
 +The x86 boot prefix code is located in ''​arch/​i386/​prefix/''​. ​ It consists of a
 +medium-specific prefix assembly file and common prefix code used for all media.
 +For example, the floppy prefix is ''​dskprefix.S''​ and most of the common code is in
 +''​libprefix.S''​.
 +
 +The machine state when gPXE begins running is medium-specific. ​ For example,
 +the floppy prefix starts with a floppy disk boot sector which the BIOS loads at
 +07c0:0000 in memory.
 +
 +The medium-specific prefix code:
 +  - initializes registers and sets up a stack.
 +  - ensures that the raw gPXE image is in memory, for example by reading it off disk.
 +  - calls ''​libprefix.S:​install''​ to decompress and install gPXE into memory. ​ When this returns the .text16 and .text segments are ready.
 +  - transfers execution to the .text16 segment. ​ After this point the prefix segment is never used again.
 +  - calls C ''​main()''​ in protected mode.  When this returns gPXE has finished executing.
 +  - calls ''​libprefix.S:​uninstall''​ to clean up before returning to firmware.
 +  - returns to firmware to boot the next device.
 +
 +Most of the work is done in ''​libprefix.S:​install''​. ​ Decompressing and installing
 +gPXE into memory is done in several stages. ​ When memory regions above the
 +first MB need to be accessed, the code switches into protected mode but always
 +switches back to real mode before completing.
 +
 +===== Debugging techniques =====
 +
 +==== Debuggers ====
 +
 +It is difficult to use debuggers at this early stage of execution because most
 +gPXE functionality is not yet available and the CPU runs in real mode.  Modern
 +debuggers may not support real mode well because applications run under
 +protected mode.
 +
 +If the issue can be reproduced in a virtual machine then it may be possible to
 +use a debugger.
 +
 +==== Printing messages ====
 +
 +Usually ''​printf()''​-style debugging is a good approach except there is no
 +''​printf()''​ function at this stage. ​ Instead consider using:
 +
 +  * ''​libprefix.S:​print_character''​ and related functions. ​ These work in real mode.
 +  * manually calling ''​int $0x10 ah=0xe''​ to print a character in real mode.
 +
 +==== Infinite loops ====
 +
 +An infinite loop can be placed along the code path to identify the location of
 +a crash. ​ If the machine hangs on the infinite loop, then the location is
 +being reached. ​ If the machine crashes, then the location is not reached.
 +
 +  1: /* Hang here for debugging */
 +  jmp 1b
 +
 +==== Reboots ====
 +
 +If the issue is a hang then it may not be possible to use an infinite loop to
 +determine where the hang occurs. ​ Instead, a reboot can be used to identify
 +where code goes wrong.
 +
 +  /* Reboot */
 +  jmpl $0xf000,​ $0xfff0

QR Code
QR Code dev:prefixdebugging (generated for current page)