Real-Mode Initialization

   

The entry point for the kernel is an assembly language routine called rdb_bootstrap(). RDB refers to the remote debugger used internally by Hewlett-Packard. This is the first point in the kernel at which the debugger can start managing the kernel. rdb_bootstrap() turns off interrupts and initializes the interrupt vector table so that we'll be ready to handle any interrupts that come in. It also creates the first procinfo structure, mpproc_info[0], and fills it with information about the monarch. It sets CR24 to point to this procinfo structure. If the kernel is compiled for 64-bit operation and the hardware is 64-bit-capable, rdb_bootstrap() turns on the W-bit in the Processor Status Word to enable wide mode.

rdb_bootstrap() then has to get ready to make a call into C code. It sets up the stack pointer (GR30) and global data pointer (GR27), creates a calling stack from, then calls realmain().

realmain() handles the portion of kernel initialization that must be done in real mode before we turn on virtual address translation. Realmain() does its work by using a calllist an array of pointers to functions. The only line in realmain() is a call to DoCalllist(), passing realmain_calllist as the first argument. DoCalllist() iterates over the functions in the realmain_calllist array, calling each one in turn. The calllist itself is constructed when the kernel is compiled, using an English-like file that describes the order of the initialization routines. This file contains the name of each routine to be called along with constraints on the order of execution which other routines it must run before or after. A program parses this file at compile time and creates the calllist.

The realmain calllist contains close to 100 routines. The following is a summary of the general functions performed by the realmain calllist.

  1. Set the transfer of control (TOC) vector in page zero of memory.

  2. Copy the arguments passed by HPUXBOOT from HPUXBOOT's address space into the kernel's.

  3. Create a temporary resource map for the IMM, indicating that memory currently used by the kernel image is busy and the rest is free. This will be used to allocate memory before the virtual memory allocator has been set up.

  4. Allocate and initialize systemwide spinlocks.

  5. Allocate buffers for IODC to use to dump memory in the event of a panic.

  6. Initialize the monarch by setting up its HPMC handler, filling in information about the processor type and enabling its coprocessors.

  7. Purge the TLB, then initialize TLB entries for kernel and graphics.

  8. Call pa_memory_init(), which scans the central bus for memory modules not yet initialized. Any memory modules found are initialized and added to the native module tree.

  9. Create another resource map real_free_map to be used to track available pages now that we have initialized the rest of memory. The resource map we had been using is copied into this new one.

  10. Create the 32-bit and 64-bit resource maps sysmap_32bit and sysmap_64bit.

  11. Using the routines provided by HPUXBOOT, read the LVM configuration from /stand/rootconf and the stored I/O configuration from /stand/ioconfig.

  12. Perform first-level I/O configuration. This calls pa_module_init() to scan the system's busses looking for modules. Each module is added to the native_mod_tree. If the module is a processor, it gets a crash table entry; if it is an I/O module, the module is reset and interrupt handlers are set up for the module.

  13. The fixed_mod_table (from /stand/ioconfig) gets merged with the native_mod_table, which contains devices we've discovered.

  14. The space used by HPUXBOOT is now freed it is no longer needed.

  15. Allocate and initialize a number of kernel data structures. These include:

    • The pgclass table, used by crashconfg(1m) to mark which pages to dump in the event of a panic

    • mpproc_info structures for non-monarch processors

    • pdir locks, the page directory, and the pfn_to_virt table

    • The I/O alias table

    • The space map

    • The inode table

    • The file table

    • The directory name lookup cache (DNLC)

    • The proc and kthread tables

    • Physio's private buffer pool

    • Processor save state areas

    • Callouts

    • Resource allocation maps for quadrants 2, 3, and 4

  16. Handcraft proc[0], the swapper. Assign it to kthread[0]. Create a virtual address space for it, and manually map it to a real address.

  17. Allocate and initialize processor idle stacks and non-monarch interrupt stacks.

  18. Map any extra I/O register sets into virtual space

  19. Each page we allocated so far while in real mode is inserted into the pdir and reserved in sysmap_32bit.

Let's have a look at where we are when realmain() completes:

  • We have discovered all our I/O devices and reset them, but have not yet assigned drivers to them.

  • The virtual memory system is initialized and ready to run.

  • The monarch is still the only processor running, although we have initialized much of the data for the other processors.

  • The file systems are unitialized.

  • The proc and thread tables are initialized, and the first entry in each is occupied by the swapper process.

When realmain() completes, it returns to its caller, rdb_bootstrap(). The next thing rdb_bootstrap() does is put us into virtual mode by setting the W, D, C, P, Q, and I bits. This gives us wide mode, data translation, code translation, protection identifier validation, interrupt state collection, and external interrupts enabled. The system is now running in virtual mode.



HP-UX 11i Internals
HP-UX 11i Internals
ISBN: 0130328618
EAN: 2147483647
Year: 2006
Pages: 167

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net