📄 boot.c
字号:
/* $NetBSD$ *//* * Copyright (C) 2001 Bruno Achauer. * Copyright (C) 2001 Exet AG. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Exet AG. * 4. The name of Exet AG may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY EXET AG ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL EXET AG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#define ELFSIZE 32 /* We use 32-bit ELF. */#include <sys/param.h>#include <machine/cpu.h>#include <machine/mpc860dev.h>#include <lib/libsa/stand.h>#include <lib/libsa/loadfile.h>#include <lib/libkern/libkern.h>#include "bootinfo.h"#include "ppcboot_defs.h"#define ROUNDED(v, r) (((v) + (r) - 1) & ~((r) - 1))#define syncicache(addr, len) __syncicache(addr, len)int boothowto;static bd_t *board_info;voidputchar (int c){ board_info->bi_mon_fnc->putc (c);}__dead void_rtt(){ for (;;);}extern char _start[], _end[], _edata[];extern char bootprog_name[], bootprog_rev[], bootprog_maker[], bootprog_date[];static struct btinfo_load *set_bootinfo (char *bootinfo, const bd_t *bd, char *consdev, char *bootargs, void **next){ void *bi_next = bi_init ((paddr_t) bootinfo); struct btinfo_ram *bi_ram; struct btinfo_load *bi_load; struct btinfo_clock *bi_clock; struct btinfo_console *bi_cons; struct btinfo_enet *bi_enet; bi_ram = bi_next; bi_ram->start = bd->bi_memstart; bi_ram->size = bd->bi_memsize; bi_next = bi_add (bi_ram, BTINFO_RAM, sizeof(*bi_ram)); if (bd->bi_flashsize) { struct btinfo_flash *bi_flash; bi_flash = bi_next; bi_flash->start = bd->bi_flashstart; bi_flash->size = bd->bi_flashsize; bi_flash->reserved = bd->bi_flashoffset; bi_next = bi_add (bi_flash, BTINFO_FLASH, sizeof(*bi_flash)); } if (bd->bi_sramsize) { bi_ram = bi_next; bi_ram->start = bd->bi_sramstart; bi_ram->size = bd->bi_sramsize; bi_next = bi_add (bi_ram, BTINFO_SRAM, sizeof(*bi_ram)); } bi_load = bi_next; bzero (bi_load, sizeof(*bi_load)); bi_next = bi_add (bi_load, BTINFO_LOAD, sizeof(*bi_load)); bi_clock = bi_next; bi_clock->intfreq = bd->bi_intfreq * 1000000; bi_clock->busfreq = bd->bi_busfreq * 1000000; bi_next = bi_add (bi_clock, BTINFO_CLOCK, sizeof(*bi_clock)); bi_cons = 0; if (consdev) { static const struct kd { const char *ppcboot; char netbsd[4]; int offset; } known[] = { { "smc1", "smc", 0x0a80 }, { "smc2", "smc", 0x0a90 }, { "scc1", "scc", 0x0a00 }, { "scc2", "scc", 0x0a20 }, { "scc3", "scc", 0x0a40 }, { "scc4", "scc", 0x0a60 }, { 0 } }; const struct kd *kp; for (kp=known ; kp->ppcboot ; kp+=1) { if (strcmp (consdev, kp->ppcboot) == 0) { bi_cons = bi_next; strcpy (bi_cons->devname, kp->netbsd); bi_cons->addr = kp->offset; bi_cons->speed = bd->bi_baudrate; break; } } } if (bi_cons) bi_next = bi_add (bi_cons, BTINFO_CONSOLE, sizeof(*bi_cons)); bi_enet = bi_next; bcopy (bd->bi_enetaddr, bi_enet->mac_addr, sizeof(bi_enet->mac_addr)); bi_next = bi_add (bi_enet, BTINFO_ENET, sizeof(*bi_enet)); if (bootargs && bootargs[0] && strlen (bootargs) < BTINFO_CMDLINE_LEN) { struct btinfo_cmdline *bi_args = bi_next; strcpy (bi_args->string, bootargs); bi_next = bi_add (bi_args, BTINFO_CMDLINE, sizeof(*bi_args)); } *next = bi_next; return bi_load;}static ssize_tload_ramdisk (const char *fname, char *addr){ ssize_t nr; int fd, rval; /* Open the file. */ if ((fd = open(fname, 0)) < 0) { WARN(("open %s", fname ? fname : "<default>")); return -1; } rval = 0; while ((nr = read (fd, addr, 1024)) > 0) { addr += nr; rval += nr; } if (nr == 0) printf ("%d=0x%x\n", rval, rval); close (fd); return nr ? -1 : rval;}voidmain (bd_t *bd, image_header_t *img, char *cons_dev, char *bootargs){ union { int alignit; char data[BOOTINFO_SIZE]; } bootinfo; volatile struct mpc860dev *immr = get_immr(); u_long *marks; struct btinfo_load *bi_load; void *bi_next; void (*entry)(); char *ssym, *esym; int msr; char file_name[64]; char rdsk_name[64]; paddr_t avail; /* clear .bss */ bzero(_edata, _end - _edata); /* make (some of) our arguments accessible */ board_info = bd; /* Disable external interrupt. */ asm ("mfmsr %0" : "=r"(msr)); msr &= ~PSL_EE; asm volatile ("mtmsr %0" :: "r"(msr)); /* Start timebase. */ immr->siu_tbscr = 0x0001; printf("\n"); printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev); printf(">> (%s, %s)\n\n", bootprog_maker, bootprog_date); bi_load = set_bootinfo ((char *) &bootinfo, bd, cons_dev, bootargs, &bi_next); file_name[0] = '\0'; rdsk_name[0] = '\0'; if (img->ih_type == IH_TYPE_MULTI) { int i; ulong *len_ptr = (ulong *) ((ulong)img + sizeof(image_header_t)); char *data_ptr = (char *) &len_ptr[1]; for (i=0 ; len_ptr[i] ; i+=1) data_ptr += sizeof(len_ptr[i]); if (len_ptr[0] && len_ptr[1]) { sprintf (file_name, "mem@0x%x,0x%x", ROUNDED(len_ptr[0], sizeof(uint32_t)) + data_ptr, ROUNDED(len_ptr[1], sizeof(uint32_t))); printf ("## image #1 (%s): ", file_name); } if (len_ptr[0] && len_ptr[1] && len_ptr[2]) { sprintf (rdsk_name, "mem@0x%x,0x%x", ROUNDED(len_ptr[0], sizeof(uint32_t)) + ROUNDED(len_ptr[1], sizeof(uint32_t)) + data_ptr, ROUNDED(len_ptr[2], sizeof(uint32_t))); } } marks = &bi_load->start; marks[MARK_START] = -0xc0000000; /* XXX: -KERNBASE */ if (loadfile(file_name, marks, LOAD_KERNEL) < 0) { printf("open: %s (%d)\n", strerror(errno), errno); for (;;); } entry = (void *)marks[MARK_ENTRY]; ssym = (void *)marks[MARK_SYM]; esym = (void *)marks[MARK_END]; avail = (paddr_t) esym; if (rdsk_name[0]) { void *rdsk_addr = (void *) ROUNDED ((int) esym, 0x1000); ssize_t rdsk_size; struct btinfo_ram *bi_ram = bi_next; printf ("## image #2 (%s): ", rdsk_name); if ((rdsk_size = load_ramdisk (rdsk_name, rdsk_addr)) < 0) { printf("open: %s (%d)\n", strerror(errno), errno); for (;;); } bi_ram->start = (unsigned) rdsk_addr; bi_ram->size = rdsk_size; bi_next = bi_add (bi_ram, BTINFO_RAMDISK, sizeof(*bi_ram)); avail = (paddr_t) rdsk_addr + ROUNDED (rdsk_size, 0x1000); } printf ("## Transferring control to NetBSD (at address %p) ...\n\n", entry); syncicache(entry, ssym - (char *)entry); (*entry)(avail, (paddr_t) &bootinfo); for (;;);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -