arch/alpha/boot/bootpz.c

Source file repositories/reference/linux-study-clean/arch/alpha/boot/bootpz.c

File Facts

System
Linux kernel
Corpus path
arch/alpha/boot/bootpz.c
Extension
.c
Size
13440 bytes
Lines
476
Domain
Architecture Layer
Bucket
arch/alpha
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

start_kernel(void)
{
	int must_move = 0;

	/* Initialize these for the decompression-in-place situation,
	   which is the smallest amount of work and most likely to
	   occur when using the normal START_ADDR of the kernel
	   (currently set to 16MB, to clear all console code.
	*/
	unsigned long uncompressed_image_start = K_KERNEL_IMAGE_START;
	unsigned long uncompressed_image_end = K_KERNEL_IMAGE_END;

	unsigned long initrd_image_start = K_INITRD_START;

	/*
	 * Note that this crufty stuff with static and envval
	 * and envbuf is because:
	 *
	 * 1. Frequently, the stack is short, and we don't want to overrun;
	 * 2. Frequently the stack is where we are going to copy the kernel to;
	 * 3. A certain SRM console required the GET_ENV output to stack.
	 *    ??? A comment in the aboot sources indicates that the GET_ENV
	 *    destination must be quadword aligned.  Might this explain the
	 *    behaviour, rather than requiring output to the stack, which
	 *    seems rather far-fetched.
	 */
	static long nbytes;
	static char envval[256] __attribute__((aligned(8)));
	register unsigned long asm_sp asm("30");

	SP_on_entry = asm_sp;

	srm_printk("Linux/Alpha BOOTPZ Loader for Linux " UTS_RELEASE "\n");

	/* Validity check the HWRPB. */
	if (INIT_HWRPB->pagesize != 8192) {
		srm_printk("Expected 8kB pages, got %ldkB\n",
		           INIT_HWRPB->pagesize >> 10);
		return;
	}
	if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
		srm_printk("Expected vptb at %p, got %p\n",
			   VPTB, (void *)INIT_HWRPB->vptb);
		return;
	}

	/* PALcode (re)initialization. */
	pal_init();

	/* Get the parameter list from the console environment variable. */
	nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
	if (nbytes < 0 || nbytes >= sizeof(envval)) {
		nbytes = 0;
	}
	envval[nbytes] = '\0';

#ifdef DEBUG_ADDRESSES
	srm_printk("START_ADDR 0x%lx\n", START_ADDR);
	srm_printk("KERNEL_ORIGIN 0x%lx\n", KERNEL_ORIGIN);
	srm_printk("KERNEL_SIZE 0x%x\n", KERNEL_SIZE);
	srm_printk("KERNEL_Z_SIZE 0x%x\n", KERNEL_Z_SIZE);
#endif

	/* Since all the SRM consoles load the BOOTP image at virtual
	 * 0x20000000, we have to ensure that the physical memory
	 * pages occupied by that image do NOT overlap the physical
	 * address range where the kernel wants to be run.  This
	 * causes real problems when attempting to cdecompress the
	 * former into the latter... :-(
	 *
	 * So, we may have to decompress/move the kernel/INITRD image
	 * virtual-to-physical someplace else first before moving
	 * kernel /INITRD to their final resting places... ;-}
	 *
	 * Sigh...
	 */

	/* First, check to see if the range of addresses occupied by
	   the bootstrapper part of the BOOTP image include any of the
	   physical pages into which the kernel will be placed for
	   execution.

	   We only need check on the final kernel image range, since we
	   will put the INITRD someplace that we can be sure is not
	   in conflict.
	 */
	if (check_range(V_BOOTSTRAPPER_START, V_BOOTSTRAPPER_END,
			K_KERNEL_DATA_START, K_KERNEL_IMAGE_END))
	{
		srm_printk("FATAL ERROR: overlap of bootstrapper code\n");

Annotation

Implementation Notes