Port-amiga archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: loadbsd memory segment (Was: NetBSD Amiga - Memory restrictions)
Karoly Balogh wrote:
>> [...] New options:
>>
>> -l : load kernel into largest memory segment (previous default
>> behaviour).
>> -M <size> : ignore memory segments which are smaller than
>> <size> MB (defaults to 2, as in previous versions).
>> [...]
>
> Shouldn't the bootsector code be adapted to the same changes? Otherwise
> the two ways of booting NetBSD could lead to inconsistent behavior.
Yes, that would be nice. Although I seem to remember that there were already
differences. Like -a or -b for "askroot"?
loadbsd.c 3.3 source attached, in case you want to try it. :)
--
Frank Wille
/* $NetBSD: loadbsd.c,v 1.37 2022/09/06 17:50:18 phx Exp $ */
/*
* Copyright (c) 1994 Michael L. Hitch
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <exec/resident.h>
#include <graphics/gfxbase.h>
#include <libraries/expansion.h>
#include <libraries/expansionbase.h>
#include <libraries/configregs.h>
#include <libraries/configvars.h>
#include <proto/expansion.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/dos.h>
/* Get definitions for boothowto */
#include "sys/reboot.h"
#include "inttypes.h"
#include "loadfile.h"
#undef AOUT_LDPGSZ
#define AOUT_LDPGSZ 8192
#undef sleep
#define sleep(n) if (!t_flag) (void)Delay(50*n)
/*
* Version history:
* 1.x Kernel startup interface version check.
* 2.0 Added symbol table end address and symbol table support.
* 2.1 03/23/94 - Round up end of fastram segment.
* Check fastram segment size for minimum of 2M.
* Use largest segment of highest priority if -p option.
* Print out fastram size in KB if not a multiple of MB.
* 2.2 03/24/94 - Zero out all unused registers.
* Started version history comment.
* 2.3 04/26/94 - Added -D option to enter debugger on boot.
* 2.4 04/30/94 - Cpuid includes base machine type.
* Also check if CPU is capable of running NetBSD.
* 2.5 05/17/94 - Add check for "A3000 bonus".
* 2.6 06/05/94 - Added -c option to override machine type.
* 2.7 06/15/94 - Pass E clock frequency.
* 2.8 06/22/94 - Fix supervisor stack usage.
* 2.9 06/26/94 - Use PAL flag for E clock freq on pre 2.0 WB
* Added AGA enable parameter
* 2.10 12/22/94 - Use FindResident() & OpenResource() for machine
* type detection.
* Add -n flag & option for non-contiguous memory.
* 01/28/95 - Corrected -n on usage & help messages.
* 2.11 03/12/95 - Check kernel size against chip memory size.
* 2.12 11/11/95 - Add -I option to inhibit synchronous transfer
* 11/12/95 - New kernel startup interface version - to
* support loading kernel image to fastmem rather than chipmem.
* 2.13 04/15/96 - Direct load to fastmem.
* Add -Z flag to force chipmem load.
* Moved test mode exit to later - kernel image is created
* and startup interface version checked in test mode.
* Add -s flag for compatibility to bootblock loader.
* 05/02/96 - Add a maximum startup interface version level
* to allow future kernel compatibility.
* 2.14 06/26/96 is - Add first version of kludges needed to
* boot on DraCos. This can probably be done a bit more cleanly
* using TTRs, but it works for now.
* 2.15 07/28/96 is - Add first version of kludges needed to
* get FusionForty kickrom'd memory back. Hope this doesn't
* break anything else.
* 2.16 07/08/00 - Added bootverbose support.
* 01/15/03 - Plugged resource leaks.
* Fixed printf() statements.
* Ansified.
* 3.0 01/16/03 - ELF support through loadfile() interface.
* 3.1 07/10/11 - Added a serial console flag
* 11/18/15 - (gnikl) Added detection of A600.
* Fix handling of multiple -n options.
* 3.2 09/02/22 - Make it compile with modern AmigaOS gcc ports.
* 3.3 01/04/22 - Loading the kernel to the highest priority memory
* segment is the default now. New option -l to revert to the
* previous behaviour of largest segment.
* New option -M to define a minimum size for the memory segment.
*/
static const char _version[] = "$VER: LoadBSD 3.3 (01.04.2023)";
/*
* Kernel startup interface version
* 1: first version of loadbsd
* 2: needs esym location passed in a4
* 3: load kernel image into fastmem rather than chipmem
* MAX: highest version with backward compatibility.
*/
#define KERNEL_STARTUP_VERSION 3
#define KERNEL_STARTUP_VERSION_MAX 9
#define DRACOREVISION (*(UBYTE *)0x02000009)
#define DRACOMMUMARGIN 0x200000
#define MAXMEMSEG 16
struct boot_memlist {
u_int m_nseg; /* num_mem; */
struct boot_memseg {
u_int ms_start;
u_int ms_size;
u_short ms_attrib;
short ms_pri;
} m_seg[MAXMEMSEG];
};
struct boot_memlist memlist;
struct boot_memlist *kmemlist;
void err(int eval, const char *, ...);
int getopt(int, char * const [], const char *);
void get_mem_config (void **, u_long *, u_long *);
void get_cpuid (void);
void get_eclock (void);
void get_AGA (void);
void usage (void);
void verbose_usage (void);
extern void startit (void *, u_long, u_long, void *, u_long, u_long, int, void *,
int, int, u_long, u_long, int);
extern u_long startit_sz;
extern char *optarg;
extern int optind;
struct ExpansionBase *ExpansionBase = NULL;
struct GfxBase *GfxBase = NULL;
u_int minmemsz = 2 * 1024 * 1024;
int p_flag = 1;
int k_flag;
int t_flag;
int reqmemsz;
int S_flag;
u_long I_flag;
int Z_flag;
u_long cpuid;
long eclock_freq;
long amiga_flags;
char *program_name;
u_char *kp;
u_long kpsz;
void
exit_func(void)
{
if (kp)
FreeMem(kp, kpsz);
if (ExpansionBase)
CloseLibrary((struct Library *)ExpansionBase);
if (GfxBase)
CloseLibrary((struct Library *)GfxBase);
}
int
main(int argc, char **argv)
{
struct ConfigDev *cd, *kcd;
u_long fmemsz, cmemsz, ksize, marks[MARK_MAX];
int boothowto, ncd, i, mem_ix, ch;
u_short kvers;
int *nkcd;
u_char *fmem;
char *esym;
void (*start_it) (void *, u_long, u_long, void *, u_long, u_long,
int, void *, int, int, u_long, u_long, int) = startit;
char *kernel_name;
atexit(exit_func);
program_name = argv[0];
boothowto = RB_SINGLE;
if (argc < 2)
usage();
if ((GfxBase = (void *)OpenLibrary(GRAPHICSNAME, 0)) == NULL)
err(20, "can't open graphics library");
if ((ExpansionBase=(void *)OpenLibrary(EXPANSIONNAME, 0)) == NULL)
err(20, "can't open expansion library");
while ((ch = getopt(argc, argv, "aAbCc:DhI:klm:M:n:qptsSvVZ")) != -1) {
switch (ch) {
case 'k':
k_flag = 1;
break;
case 'a':
boothowto &= ~(RB_SINGLE);
boothowto |= RB_AUTOBOOT;
break;
case 'b':
boothowto |= RB_ASKNAME;
break;
case 'p':
p_flag = 1;
break;
case 'l':
p_flag = 0;
break;
case 't':
t_flag = 1;
break;
case 'm':
reqmemsz = atoi(optarg) * 1024;
break;
case 'M':
minmemsz = atoi(optarg) * 1024 * 1024;
break;
case 's':
boothowto &= ~(RB_AUTOBOOT);
boothowto |= RB_SINGLE;
break;
case 'q':
boothowto |= AB_QUIET;
break;
case 'v':
boothowto |= AB_VERBOSE;
break;
case 'V':
fprintf(stderr,"%s\n",_version + 6);
break;
case 'S':
S_flag = 1;
break;
case 'D':
boothowto |= RB_KDB;
break;
case 'c':
cpuid = atoi(optarg) << 16;
break;
case 'A':
amiga_flags |= 1;
break;
case 'n':
i = atoi(optarg);
if (i >= 0 && i <= 3) {
amiga_flags &= ~(3 << 1);
amiga_flags |= i << 1;
}
else
err(20, "-n option must be 0, 1, 2, or 3");
break;
case 'C':
amiga_flags |= (1 << 3);
break;
case 'I':
I_flag = strtoul(optarg, NULL, 16);
break;
case 'Z':
Z_flag = 1;
break;
case 'h':
verbose_usage();
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc != 1)
usage();
kernel_name = argv[0];
for (cd = 0, ncd = 0; cd = FindConfigDev(cd, -1, -1); ncd++)
;
get_cpuid();
get_mem_config((void **)&fmem, &fmemsz, &cmemsz);
get_eclock();
get_AGA();
/*
* XXX Call loadfile with COUNT* options to get size
* XXX Allocate memory for kernel + additional data
* XXX Call loadfile with LOAD* options to load text/data/symbols
*/
marks[MARK_START] = 0;
if (loadfile(kernel_name, marks,
COUNT_TEXT|COUNT_TEXTA|COUNT_DATA|COUNT_BSS|
(S_flag ? (COUNT_SYM|COUNT_HDR) : 0)) == -1) {
err(20, "unable to parse kernel image");
}
ksize = ((marks[MARK_END] + 3) & ~3)
+ sizeof(*nkcd) + ncd * sizeof(*cd)
+ sizeof(*nkcd) + memlist.m_nseg * sizeof(struct boot_memseg);
if (t_flag) {
for (i = 0; i < memlist.m_nseg; ++i) {
printf("mem segment %d: start=%08x size=%08x"
" attribute=%04x pri=%d\n",
i + 1,
memlist.m_seg[i].ms_start,
memlist.m_seg[i].ms_size,
memlist.m_seg[i].ms_attrib,
memlist.m_seg[i].ms_pri);
}
printf("kernel size: %lu\n", ksize);
}
kpsz = ksize + 256 + startit_sz;
kp = (u_char *)AllocMem(kpsz, MEMF_FAST|MEMF_REVERSE);
if (kp == NULL)
err(20, "failed alloc %d", ksize);
marks[MARK_START] = (u_long)kp;
if (loadfile(kernel_name, marks,
LOAD_TEXT|LOAD_TEXTA|LOAD_DATA|LOAD_BSS|
(S_flag ? (LOAD_SYM|LOAD_HDR) : 0)) == -1) {
err(20, "unable to load kernel image");
}
marks[MARK_END] = (marks[MARK_END] + 3) & ~3;
if (k_flag) {
fmem += 4 * 1024 * 1024;
fmemsz -= 4 * 1024 * 1024;
}
if (reqmemsz && reqmemsz <= fmemsz)
fmemsz = reqmemsz;
if (boothowto & RB_AUTOBOOT)
printf("Autobooting...");
if (boothowto & RB_ASKNAME)
printf("Askboot...");
printf("Using %lu%c FASTMEM at 0x%lx, %luM CHIPMEM\n",
(fmemsz & 0xfffff) ? fmemsz >> 10 : fmemsz >> 20,
(fmemsz & 0xfffff) ? 'K' : 'M', (u_long)fmem, cmemsz >> 20);
kvers = *(u_short *)(marks[MARK_ENTRY] - 2);
if (kvers == 0x4e73) kvers = 0;
if (kvers > KERNEL_STARTUP_VERSION_MAX)
err(20, "newer loadbsd required: %d\n", kvers);
if (kvers > KERNEL_STARTUP_VERSION) {
printf("****************************************************\n"
"*** Notice: this kernel has features which require\n"
"*** a newer version of loadbsd. To allow the use of\n"
"*** any newer features or capabilities, you should\n"
"*** update to a newer version of loadbsd\n"
"****************************************************\n");
sleep(3); /* even more time to see that message */
}
/*
* give them a chance to read the information...
*/
sleep(2);
nkcd = (int *)marks[MARK_END];
esym = 0;
/*
* If symbols loaded and kernel can handle them, set esym to end.
*/
if (marks[MARK_SYM] != marks[MARK_START]) {
if (kvers > 1) {
esym = (void *)(marks[MARK_END] - marks[MARK_START]);
}
else {
/*
* suppress symbols
*/
nkcd = (int *)marks[MARK_SYM];
}
}
*nkcd = ncd;
kcd = (struct ConfigDev *)(nkcd + 1);
while((cd = FindConfigDev(cd, -1, -1))) {
u_char *ba = kcd->cd_BoardAddr;
memcpy(kcd, cd, sizeof(*kcd));
if (((cpuid >> 24) == 0x7d) && ((u_long)ba < 0x1000000)) {
if (t_flag)
printf("Transformed Z2 device from %08lx ", (u_long)ba);
ba += 0x3000000;
kcd->cd_BoardAddr = ba;
if (t_flag)
printf("to %08lx\n", (u_long)ba);
}
++kcd;
}
kmemlist = (struct boot_memlist *)kcd;
kmemlist->m_nseg = memlist.m_nseg;
for (mem_ix = 0; mem_ix < memlist.m_nseg; mem_ix++)
kmemlist->m_seg[mem_ix] = memlist.m_seg[mem_ix];
if (kvers > 2 && Z_flag == 0) {
/*
* Kernel supports direct load to fastmem, and the -Z
* option was not specified. Copy startup code to end
* of kernel image and set start_it.
*/
if (ksize >= fmemsz) {
printf("Kernel size %lu exceeds best Fast Memory segment of %lu\n",
ksize, fmemsz);
err(20, "Insufficient Fast Memory for kernel");
}
if (kp < fmem) {
printf("Kernel at %08lx, Fastmem used at %08lx\n",
(u_long)kp, (u_long)fmem);
err(20, "Can't copy upwards yet.\nDefragment your memory and try again OR try the -p OR try the -Z options.");
}
start_it = (void (*)())(kp + ksize + 256);
memcpy((void *)start_it, (void *)startit, startit_sz);
CacheClearU();
printf("*** Loading from %08lx to Fastmem %08lx ***\n",
(u_long)kp, (u_long)fmem);
sleep(2);
} else {
/*
* Either the kernel doesn't support loading directly to
* fastmem or the -Z flag was given. Verify kernel image
* fits into chipmem.
*/
if (ksize >= cmemsz) {
printf("Kernel size %lu exceeds Chip Memory of %lu\n",
ksize, cmemsz);
err(20, "Insufficient Chip Memory for kernel");
}
Z_flag = 1;
printf("*** Loading from %08lx to Chipmem ***\n", (u_long)kp);
}
/*
* if test option set, done
*/
if (t_flag) {
exit(0);
}
/*
* XXX AGA startup - may need more
*/
LoadView(NULL); /* Don't do this if AGA active? */
start_it(kp, ksize, marks[MARK_ENTRY] - marks[MARK_START], fmem, fmemsz, cmemsz,
boothowto, esym, cpuid, eclock_freq, amiga_flags, I_flag, Z_flag == 0);
/*NOTREACHED*/
}
void
get_mem_config(void **fmem, u_long *fmemsz, u_long *cmemsz)
{
struct MemHeader *mh, *nmh;
u_int nmem, eseg, segsz, seg, nseg, nsegsz;
char mempri;
nmem = 0;
mempri = -128;
*fmemsz = 0;
*cmemsz = 0;
*fmem = NULL;
/*
* walk through the exec memory list
*/
Forbid();
for (mh = (void *) SysBase->MemList.lh_Head;
nmh = (void *) mh->mh_Node.ln_Succ; mh = nmh) {
nseg = (u_int)mh->mh_Lower;
nsegsz = (u_int)mh->mh_Upper - nseg;
segsz = nsegsz;
seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, 0L);
nsegsz -= segsz, nseg += segsz;
for (;segsz;
segsz = nsegsz,
seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, DMA_Continue),
nsegsz -= segsz, nseg += segsz, ++nmem) {
if (t_flag)
printf("Translated %08x sz %08x to %08x sz %08x\n",
nseg - segsz, nsegsz + segsz, seg, segsz);
eseg = seg + segsz;
if ((cpuid >> 24) == 0x7D) {
/* DraCo MMU table kludge */
segsz = ((segsz -1) | 0xfffff) + 1;
seg = eseg - segsz;
/*
* Only use first SIMM to boot; we know it is VA==PA.
* Enter into table and continue. Yes,
* this is ugly.
*/
if (seg != 0x40000000) {
memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
memlist.m_seg[nmem].ms_size = segsz;
memlist.m_seg[nmem].ms_start = seg;
++nmem;
continue;
}
memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
memlist.m_seg[nmem].ms_size = DRACOMMUMARGIN;
memlist.m_seg[nmem].ms_start = seg;
++nmem;
seg += DRACOMMUMARGIN;
segsz -= DRACOMMUMARGIN;
}
memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
memlist.m_seg[nmem].ms_size = segsz;
memlist.m_seg[nmem].ms_start = seg;
if ((mh->mh_Attributes & (MEMF_CHIP|MEMF_FAST)) == MEMF_CHIP) {
/*
* there should hardly be more than one entry for
* chip mem, but handle it the same nevertheless
* cmem always starts at 0, so include vector area
*/
memlist.m_seg[nmem].ms_start = seg = 0;
/*
* round to multiple of 512K
*/
segsz = (segsz + 512 * 1024 - 1) & -(512 * 1024);
memlist.m_seg[nmem].ms_size = segsz;
if (segsz > *cmemsz)
*cmemsz = segsz;
continue;
}
/*
* some heuristics..
*/
seg &= -AOUT_LDPGSZ;
eseg = (eseg + AOUT_LDPGSZ - 1) & -AOUT_LDPGSZ;
/*
* get the mem back stolen by incore kickstart on
* A3000 with V36 bootrom.
*/
if (eseg == 0x07f80000)
eseg = 0x08000000;
/*
* or by zkick on a A2000.
*/
if (seg == 0x280000 &&
strcmp(mh->mh_Node.ln_Name, "zkick memory") == 0)
seg = 0x200000;
/*
* or by Fusion Forty fastrom
*/
if ((seg & ~(1024*1024-1)) == 0x11000000) {
/*
* XXX we should test the name.
* Unfortunately, the memory is just called
* "32 bit memory" which isn't very specific.
*/
seg = 0x11000000;
}
segsz = eseg - seg;
memlist.m_seg[nmem].ms_start = seg;
memlist.m_seg[nmem].ms_size = segsz;
/*
* If this segment is smaller than minmemsz (default: 2M),
* don't use it to load the kernel
*/
if (segsz < minmemsz)
continue;
/*
* if p_flag is set, select memory by priority
* instead of size
*/
if ((!p_flag && segsz > *fmemsz) || (p_flag &&
mempri <= mh->mh_Node.ln_Pri && segsz > *fmemsz)) {
*fmemsz = segsz;
*fmem = (void *)seg;
mempri = mh->mh_Node.ln_Pri;
}
}
}
memlist.m_nseg = nmem;
Permit();
}
/*
* Try to determine the machine ID by searching the resident module list
* for modules only present on specific machines. (Thanks, Bill!)
*/
void
get_cpuid(void)
{
cpuid |= SysBase->AttnFlags; /* get FPU and CPU flags */
if ((cpuid & AFB_68020) == 0)
err(20, "CPU not supported");
if (cpuid & 0xffff0000) {
if ((cpuid >> 24) == 0x7D)
return;
switch (cpuid >> 16) {
case 500:
case 600:
case 1000:
case 1200:
case 2000:
case 3000:
case 4000:
return;
default:
printf("machine Amiga %lu is not recognized\n",
cpuid >> 16);
exit(1);
}
}
if (FindResident("A4000 Bonus") || FindResident("A4000 bonus")
|| FindResident("A1000 Bonus"))
cpuid |= 4000 << 16;
else if (FindResident("A3000 Bonus") || FindResident("A3000 bonus"))
cpuid |= 3000 << 16;
else if (OpenResource("card.resource")) {
UBYTE alicerev = *((UBYTE *)0xdff004) & 0x6f;
if (alicerev == 0x22 || alicerev == 0x23)
cpuid |= 1200 << 16; /* AGA + PCMCIA = A1200 */
else
cpuid |= 600 << 16; /* noAGA + PCMCIA = A600 */
} else if (OpenResource("draco.resource")) {
cpuid |= (32000 | DRACOREVISION) << 16;
}
/*
* Nothing found, it's probably an A2000 or A500
*/
if ((cpuid >> 16) == 0)
cpuid |= 2000 << 16;
}
void
get_eclock(void)
{
/* Fix for 1.3 startups? */
if (SysBase->LibNode.lib_Version > 36)
eclock_freq = SysBase->ex_EClockFrequency;
else
eclock_freq = (GfxBase->DisplayFlags & PAL) ?
709379 : 715909;
}
void
get_AGA(void)
{
/*
* Determine if an AGA mode is active
*/
}
void
usage(void)
{
fprintf(stderr, "usage: %s [-abhklpstACDSVZ] [-c machine] [-m size] [-M size] [-n mode] [-I sync-inhibit] kernel\n",
program_name);
exit(1);
}
void
verbose_usage(void)
{
fprintf(stderr, "\n\
NAME\n\
\t%s - loads NetBSD from amiga dos.\n\
SYNOPSIS\n\
\t%s [-abhklpstACDSVZ] [-c machine] [-m size] [-M size] [-n mode] [-I sync-inhibit] kernel\n\
OPTIONS\n\
\t-a Boot up to multiuser mode.\n\
\t-A Use AGA display mode, if available.\n\
\t-b Ask for which root device.\n\
\t It is possible to have multiple roots and choose between them.\n\
\t-c Set machine type. [e.g 3000; use 32000+N for DraCo rev. N]\n\
\t-C Use Serial Console.\n\
\t-D Enter debugger\n\
\t-h This help message.\n\
\t-I Inhibit sync negotiation. Option value is bit-encoded targets.\n\
\t-k Reserve the first 4M of fast mem [Some one else\n\
\t is going to have to answer what that it is used for].\n\
\t-l Use the largest memory segment for loading the kernel.\n\
\t-m Tweak amount of available memory, for finding minimum amount\n\
\t of memory required to run. Sets fastmem size to specified\n\
\t size in Kbytes.\n\
\t-M Request a minimum size in Mbytes for the kernel's memory\n\
\t segment. Defaults to 2M.\n\
\t-n Enable multiple non-contiguous memory: value = 0 (disabled),\n\
\t 1 (two segments), 2 (all avail segments), 3 (same as 2?).\n\
\t-p Use highest priority fastmem segment for loading the kernel.\n\
\t This is the default.\n\
\t-q Boot up in quiet mode.\n\
\t-s Boot up in singleuser mode (default).\n\
\t-S Include kernel symbol table.\n\
\t-t This is a *test* option. It prints out the memory\n\
\t list information being passed to the kernel and also\n\
\t exits without actually starting NetBSD.\n\
\t-v Boot up in verbose mode.\n\
\t-V Version of loadbsd program.\n\
\t-Z Force kernel load to chipmem.\n\
HISTORY\n\
\tThis version supports Kernel version 720 +\n",
program_name, program_name);
exit(1);
}
static void
_Vdomessage(int doerrno, const char *fmt, va_list args)
{
fprintf(stderr, "%s: ", program_name);
if (fmt) {
vfprintf(stderr, fmt, args);
fprintf(stderr, ": ");
}
if (doerrno) {
fprintf(stderr, "%s", strerror(errno));
}
fprintf(stderr, "\n");
}
void
err(int eval, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
_Vdomessage(1, fmt, ap);
va_end(ap);
exit(eval);
}
void
warn(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
_Vdomessage(1, fmt, ap);
va_end(ap);
}
Home |
Main Index |
Thread Index |
Old Index