Implement new crash dump format. Mostly taken from hp300, extended to
support multiple physical RAM segments by me. Garbage collect functions obsoleted by this change.
This commit is contained in:
parent
1cf91041df
commit
c1c244e0a3
|
@ -0,0 +1,8 @@
|
||||||
|
/* $NetBSD: kcore.h,v 1.1 1997/04/23 19:15:16 scottr Exp $ */
|
||||||
|
|
||||||
|
#ifndef _MACHINE_KCORE_H_
|
||||||
|
#define _MACHINE_KCORE_H_
|
||||||
|
|
||||||
|
#include <m68k/kcore.h>
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: machdep.c,v 1.145 1997/04/16 07:16:49 scottr Exp $ */
|
/* $NetBSD: machdep.c,v 1.146 1997/04/23 19:15:21 scottr Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
|
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
|
||||||
|
@ -87,6 +87,8 @@
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/buf.h>
|
#include <sys/buf.h>
|
||||||
#include <sys/exec.h>
|
#include <sys/exec.h>
|
||||||
|
#include <sys/core.h>
|
||||||
|
#include <sys/kcore.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
|
@ -121,6 +123,7 @@
|
||||||
#include <machine/psl.h>
|
#include <machine/psl.h>
|
||||||
#include <machine/pte.h>
|
#include <machine/pte.h>
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
|
#include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */
|
||||||
#include <net/netisr.h>
|
#include <net/netisr.h>
|
||||||
|
|
||||||
#define MAXMEM 64*1024*CLSIZE /* XXX - from cmap.h */
|
#define MAXMEM 64*1024*CLSIZE /* XXX - from cmap.h */
|
||||||
|
@ -219,10 +222,20 @@ static iomem_malloc_safe;
|
||||||
|
|
||||||
static void identifycpu __P((void));
|
static void identifycpu __P((void));
|
||||||
static u_long get_physical __P((u_int, u_long *));
|
static u_long get_physical __P((u_int, u_long *));
|
||||||
void dumpsys __P((void));
|
|
||||||
|
|
||||||
int bus_mem_add_mapping __P((bus_addr_t, bus_size_t,
|
int cpu_dumpsize __P((void));
|
||||||
int, bus_space_handle_t *));
|
int cpu_dump __P((int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *));
|
||||||
|
void cpu_init_kcore_hdr __P((void));
|
||||||
|
|
||||||
|
void dumpsys __P((void));
|
||||||
|
|
||||||
|
int bus_mem_add_mapping __P((bus_addr_t, bus_size_t,
|
||||||
|
int, bus_space_handle_t *));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-dependent crash dump header info.
|
||||||
|
*/
|
||||||
|
cpu_kcore_hdr_t cpu_kcore_hdr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Console initialization: called early on from main,
|
* Console initialization: called early on from main,
|
||||||
|
@ -269,6 +282,11 @@ cpu_startup(void)
|
||||||
vm_size_t size = 0; /* To avoid compiler warning */
|
vm_size_t size = 0; /* To avoid compiler warning */
|
||||||
int delay;
|
int delay;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the kernel crash dump header.
|
||||||
|
*/
|
||||||
|
cpu_init_kcore_hdr();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize error message buffer (at end of core).
|
* Initialize error message buffer (at end of core).
|
||||||
* high[numranges-1] was decremented in pmap_bootstrap.
|
* high[numranges-1] was decremented in pmap_bootstrap.
|
||||||
|
@ -537,10 +555,8 @@ cpu_reboot(howto, bootstr)
|
||||||
splhigh();
|
splhigh();
|
||||||
|
|
||||||
/* If rebooting and a dump is requested, do it. */
|
/* If rebooting and a dump is requested, do it. */
|
||||||
if (howto & RB_DUMP) {
|
if (howto & RB_DUMP)
|
||||||
savectx(&dumppcb); /* XXX this goes away soon */
|
|
||||||
dumpsys();
|
dumpsys();
|
||||||
}
|
|
||||||
|
|
||||||
haltsys:
|
haltsys:
|
||||||
/* Run any shutdown hooks. */
|
/* Run any shutdown hooks. */
|
||||||
|
@ -566,17 +582,157 @@ cpu_reboot(howto, bootstr)
|
||||||
* Map ROM where the MacOS likes it, so we can reboot,
|
* Map ROM where the MacOS likes it, so we can reboot,
|
||||||
* hopefully.
|
* hopefully.
|
||||||
*/
|
*/
|
||||||
pmap_map(MacOSROMBase, MacOSROMBase,
|
pmap_map(MacOSROMBase, MacOSROMBase, MacOSROMBase + 4 * 1024 * 1024,
|
||||||
MacOSROMBase + 4 * 1024 * 1024,
|
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
|
|
||||||
|
|
||||||
|
|
||||||
printf("rebooting...\n");
|
printf("rebooting...\n");
|
||||||
DELAY(1000000);
|
DELAY(1000000);
|
||||||
doboot();
|
doboot();
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the kernel crash dump header.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_init_kcore_hdr()
|
||||||
|
{
|
||||||
|
cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
|
||||||
|
struct m68k_kcore_hdr *m = &h->un._m68k;
|
||||||
|
int i, j, k;
|
||||||
|
extern char end[];
|
||||||
|
|
||||||
|
bzero(&cpu_kcore_hdr, sizeof(cpu_kcore_hdr));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the `dispatcher' portion of the header.
|
||||||
|
*/
|
||||||
|
strcpy(h->name, machine);
|
||||||
|
h->page_size = NBPG;
|
||||||
|
h->kernbase = KERNBASE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in information about our MMU configuration.
|
||||||
|
*/
|
||||||
|
m->mmutype = mmutype;
|
||||||
|
m->sg_v = SG_V;
|
||||||
|
m->sg_frame = SG_FRAME;
|
||||||
|
m->sg_ishift = SG_ISHIFT;
|
||||||
|
m->sg_pmask = SG_PMASK;
|
||||||
|
m->sg40_shift1 = SG4_SHIFT1;
|
||||||
|
m->sg40_mask2 = SG4_MASK2;
|
||||||
|
m->sg40_shift2 = SG4_SHIFT2;
|
||||||
|
m->sg40_mask3 = SG4_MASK3;
|
||||||
|
m->sg40_shift3 = SG4_SHIFT3;
|
||||||
|
m->sg40_addr1 = SG4_ADDR1;
|
||||||
|
m->sg40_addr2 = SG4_ADDR2;
|
||||||
|
m->pg_v = PG_V;
|
||||||
|
m->pg_frame = PG_FRAME;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize pointer to kernel segment table.
|
||||||
|
*/
|
||||||
|
m->sysseg_pa = (u_int32_t)(pmap_kernel()->pm_stpa);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize relocation value such that:
|
||||||
|
*
|
||||||
|
* pa = (va - KERNBASE) + reloc
|
||||||
|
*/
|
||||||
|
m->reloc = load_addr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the end of the relocatable range.
|
||||||
|
*/
|
||||||
|
m->relocend = (u_int32_t)end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mac68k has multiple RAM segments on some models.
|
||||||
|
*/
|
||||||
|
m->ram_segs[0].start = low[0];
|
||||||
|
m->ram_segs[0].size = high[0] - low[0];
|
||||||
|
for (i = 1; i < numranges; i++) {
|
||||||
|
if ((high[i] - low[i]) == 0)
|
||||||
|
continue; /* shouldn't happen, but be safe */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sort and coalesce RAM segments, as required by libkvm.
|
||||||
|
*/
|
||||||
|
for (j = 0; m->ram_segs[j].size; j++) {
|
||||||
|
if (low[i] < m->ram_segs[j].start)
|
||||||
|
break; /* Insert before this segment */
|
||||||
|
if (low[i] <=
|
||||||
|
(m->ram_segs[j].start + m->ram_segs[j].size))
|
||||||
|
break; /* Overlapping or adjoining */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->ram_segs[j].size) {
|
||||||
|
if (low[i] < m->ram_segs[j].start) {
|
||||||
|
/* Make room for new segment. */
|
||||||
|
for (k = j; m->ram_segs[k].size; k++)
|
||||||
|
/* counting... */;
|
||||||
|
for (; k > j; k--) {
|
||||||
|
m->ram_segs[k].start =
|
||||||
|
m->ram_segs[k - 1].start;
|
||||||
|
m->ram_segs[k].size =
|
||||||
|
m->ram_segs[k - 1].size;
|
||||||
|
}
|
||||||
|
} else if (low[i] <=
|
||||||
|
(m->ram_segs[j].start + m->ram_segs[j].size)) {
|
||||||
|
/* Coalesce segments. */
|
||||||
|
if (high[i] > (m->ram_segs[j].start +
|
||||||
|
m->ram_segs[j].size))
|
||||||
|
m->ram_segs[j].size =
|
||||||
|
high[i] - m->ram_segs[j].start;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m->ram_segs[j].start = low[i];
|
||||||
|
m->ram_segs[j].size = high[i] - low[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the size of the machine-dependent crash dump header.
|
||||||
|
* Returns size in disk blocks.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cpu_dumpsize()
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
|
||||||
|
return (btodb(roundup(size, dbtob(1))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by dumpsys() to dump the machine-dependent header.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cpu_dump(dump, blknop)
|
||||||
|
int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
|
||||||
|
daddr_t *blknop;
|
||||||
|
{
|
||||||
|
int buf[dbtob(1) / sizeof(int)];
|
||||||
|
cpu_kcore_hdr_t *chdr;
|
||||||
|
kcore_seg_t *kseg;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
kseg = (kcore_seg_t *)buf;
|
||||||
|
chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
|
||||||
|
sizeof(int)];
|
||||||
|
|
||||||
|
/* Create the segment header. */
|
||||||
|
CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
|
||||||
|
kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t));
|
||||||
|
|
||||||
|
bcopy(&cpu_kcore_hdr, chdr, sizeof(cpu_kcore_hdr_t));
|
||||||
|
error = (*dump)(dumpdev, *blknop, (caddr_t)buf, sizeof(buf));
|
||||||
|
*blknop += btodb(sizeof(buf));
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These variables are needed by /sbin/savecore
|
* These variables are needed by /sbin/savecore
|
||||||
*/
|
*/
|
||||||
|
@ -584,20 +740,6 @@ u_long dumpmag = 0x8fca0101; /* magic number */
|
||||||
int dumpsize = 0; /* pages */
|
int dumpsize = 0; /* pages */
|
||||||
long dumplo = 0; /* blocks */
|
long dumplo = 0; /* blocks */
|
||||||
|
|
||||||
static int get_max_page __P((void));
|
|
||||||
|
|
||||||
static int
|
|
||||||
get_max_page()
|
|
||||||
{
|
|
||||||
int i, max = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < numranges; i++) {
|
|
||||||
if (high[i] > max)
|
|
||||||
max = high[i];
|
|
||||||
}
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called by main to set dumplo and dumpsize.
|
* This is called by main to set dumplo and dumpsize.
|
||||||
* Dumps always skip the first CLBYTES of disk space in
|
* Dumps always skip the first CLBYTES of disk space in
|
||||||
|
@ -608,8 +750,12 @@ get_max_page()
|
||||||
void
|
void
|
||||||
cpu_dumpconf()
|
cpu_dumpconf()
|
||||||
{
|
{
|
||||||
int nblks;
|
cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
|
||||||
int maj;
|
struct m68k_kcore_hdr *m = &h->un._m68k;
|
||||||
|
int chdrsize; /* size of dump header */
|
||||||
|
int nblks; /* size of dump area */
|
||||||
|
int maj;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (dumpdev == NODEV)
|
if (dumpdev == NODEV)
|
||||||
return;
|
return;
|
||||||
|
@ -620,20 +766,123 @@ cpu_dumpconf()
|
||||||
if (bdevsw[maj].d_psize == NULL)
|
if (bdevsw[maj].d_psize == NULL)
|
||||||
return;
|
return;
|
||||||
nblks = (*bdevsw[maj].d_psize) (dumpdev);
|
nblks = (*bdevsw[maj].d_psize) (dumpdev);
|
||||||
if (nblks <= ctod(1))
|
chdrsize = cpu_dumpsize();
|
||||||
|
|
||||||
|
dumpsize = 0;
|
||||||
|
for (i = 0; m->ram_segs[i].size && i < M68K_NPHYS_RAM_SEGS; i++)
|
||||||
|
dumpsize += btoc(m->ram_segs[i].size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see if we will fit. Note we always skip the
|
||||||
|
* first CLBYTES in case there is a disk label there.
|
||||||
|
*/
|
||||||
|
if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
|
||||||
|
dumpsize = 0;
|
||||||
|
dumplo = -1;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dumpsize = btoc(get_max_page());
|
/*
|
||||||
|
* Put dump at the end of the partition.
|
||||||
|
*/
|
||||||
|
dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
|
||||||
|
}
|
||||||
|
|
||||||
/* Always skip the first CLBYTES, in case there is a label there. */
|
void
|
||||||
if (dumplo < ctod(1))
|
dumpsys()
|
||||||
dumplo = ctod(1);
|
{
|
||||||
|
cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
|
||||||
|
struct m68k_kcore_hdr *m = &h->un._m68k;
|
||||||
|
daddr_t blkno; /* current block to write */
|
||||||
|
/* dump routine */
|
||||||
|
int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
|
||||||
|
int pg; /* page being dumped */
|
||||||
|
vm_offset_t maddr; /* PA being dumped */
|
||||||
|
int seg; /* RAM segment being dumped */
|
||||||
|
int error; /* error code from (*dump)() */
|
||||||
|
|
||||||
/* Put dump at end of partition, and make it fit. */
|
/* XXX initialized here because of gcc lossage */
|
||||||
if (dumpsize > dtoc(nblks - dumplo))
|
seg = 0;
|
||||||
dumpsize = dtoc(nblks - dumplo);
|
maddr = m->ram_segs[seg].start;
|
||||||
if (dumplo < nblks - ctod(dumpsize))
|
pg = 0;
|
||||||
dumplo = nblks - ctod(dumpsize);
|
|
||||||
|
/* Don't put dump messages in msgbuf. */
|
||||||
|
msgbufmapped = 0;
|
||||||
|
|
||||||
|
/* Make sure dump device is valid. */
|
||||||
|
if (dumpdev == NODEV)
|
||||||
|
return;
|
||||||
|
if (dumpsize == 0) {
|
||||||
|
cpu_dumpconf();
|
||||||
|
if (dumpsize == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dumplo < 0)
|
||||||
|
return;
|
||||||
|
dump = bdevsw[major(dumpdev)].d_dump;
|
||||||
|
blkno = dumplo;
|
||||||
|
|
||||||
|
printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
|
||||||
|
|
||||||
|
printf("dump ");
|
||||||
|
|
||||||
|
/* Write the dump header. */
|
||||||
|
error = cpu_dump(dump, &blkno);
|
||||||
|
if (error)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
for (pg = 0; pg < dumpsize; pg++) {
|
||||||
|
#define NPGMB (1024*1024/NBPG)
|
||||||
|
/* print out how many MBs we have dumped */
|
||||||
|
if (pg && (pg % NPGMB) == 0)
|
||||||
|
printf("%d ", pg / NPGMB);
|
||||||
|
#undef NPGMB
|
||||||
|
while (maddr >=
|
||||||
|
(m->ram_segs[seg].start + m->ram_segs[seg].size)) {
|
||||||
|
if (++seg >= M68K_NPHYS_RAM_SEGS ||
|
||||||
|
m->ram_segs[seg].size == 0) {
|
||||||
|
error = EINVAL; /* XXX ?? */
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
maddr = m->ram_segs[seg].start;
|
||||||
|
}
|
||||||
|
pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr,
|
||||||
|
VM_PROT_READ, TRUE);
|
||||||
|
|
||||||
|
error = (*dump)(dumpdev, blkno, vmmap, NBPG);
|
||||||
|
bad:
|
||||||
|
switch (error) {
|
||||||
|
case 0:
|
||||||
|
maddr += NBPG;
|
||||||
|
blkno += btodb(NBPG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENXIO:
|
||||||
|
printf("device bad\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EFAULT:
|
||||||
|
printf("device not ready\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EINVAL:
|
||||||
|
printf("area improper\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EIO:
|
||||||
|
printf("i/o error\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EINTR:
|
||||||
|
printf("aborted from console\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("error %d\n", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("succeeded\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -645,8 +894,6 @@ cpu_dumpconf()
|
||||||
static vm_offset_t dumpspace;
|
static vm_offset_t dumpspace;
|
||||||
|
|
||||||
vm_offset_t reserve_dumppages __P((vm_offset_t));
|
vm_offset_t reserve_dumppages __P((vm_offset_t));
|
||||||
static int find_range __P((vm_offset_t));
|
|
||||||
static int find_next_range __P((vm_offset_t));
|
|
||||||
|
|
||||||
vm_offset_t
|
vm_offset_t
|
||||||
reserve_dumppages(p)
|
reserve_dumppages(p)
|
||||||
|
@ -656,142 +903,6 @@ reserve_dumppages(p)
|
||||||
return (p + BYTES_PER_DUMP);
|
return (p + BYTES_PER_DUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
find_range(pa)
|
|
||||||
vm_offset_t pa;
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < numranges; i++) {
|
|
||||||
if (low[i] <= pa && pa < high[i])
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
find_next_range(pa)
|
|
||||||
vm_offset_t pa;
|
|
||||||
{
|
|
||||||
int i, near, best, t;
|
|
||||||
|
|
||||||
near = -1;
|
|
||||||
best = 0x7FFFFFFF;
|
|
||||||
for (i = 0; i < numranges; i++) {
|
|
||||||
if (low[i] <= pa && pa < high[i])
|
|
||||||
return i;
|
|
||||||
t = low[i] - pa;
|
|
||||||
if (t > 0) {
|
|
||||||
if (t < best) {
|
|
||||||
near = i;
|
|
||||||
best = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return near;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dumpsys()
|
|
||||||
{
|
|
||||||
unsigned bytes, i, n;
|
|
||||||
int range;
|
|
||||||
int maddr, psize;
|
|
||||||
daddr_t blkno;
|
|
||||||
int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
msgbufmapped = 0; /* don't record dump msgs in msgbuf */
|
|
||||||
if (dumpdev == NODEV)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For dumps during autoconfiguration,
|
|
||||||
* if dump device has already configured...
|
|
||||||
*/
|
|
||||||
if (dumpsize == 0)
|
|
||||||
cpu_dumpconf();
|
|
||||||
if (dumplo < 0)
|
|
||||||
return;
|
|
||||||
printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
|
|
||||||
|
|
||||||
psize = (*bdevsw[major(dumpdev)].d_psize) (dumpdev);
|
|
||||||
printf("dump ");
|
|
||||||
if (psize == -1) {
|
|
||||||
printf("area unavailable.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bytes = get_max_page();
|
|
||||||
maddr = 0;
|
|
||||||
range = find_range(0);
|
|
||||||
blkno = dumplo;
|
|
||||||
dump = bdevsw[major(dumpdev)].d_dump;
|
|
||||||
for (i = 0; i < bytes; i += n) {
|
|
||||||
/*
|
|
||||||
* Avoid dumping "holes."
|
|
||||||
*/
|
|
||||||
if ((range == -1) || (i >= high[range])) {
|
|
||||||
range = find_next_range(i);
|
|
||||||
if (range == -1) {
|
|
||||||
error = EIO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
n = low[range] - i;
|
|
||||||
maddr += n;
|
|
||||||
blkno += btodb(n);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Print out how many MBs we have to go. */
|
|
||||||
n = bytes - i;
|
|
||||||
if (n && (n % (1024 * 1024)) == 0)
|
|
||||||
printf("%d ", n / (1024 * 1024));
|
|
||||||
|
|
||||||
/* Limit size for next transfer. */
|
|
||||||
if (n > BYTES_PER_DUMP)
|
|
||||||
n = BYTES_PER_DUMP;
|
|
||||||
|
|
||||||
(void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ);
|
|
||||||
error = (*dump) (dumpdev, blkno, (caddr_t) dumpspace, n);
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
maddr += n;
|
|
||||||
blkno += btodb(n); /* XXX? */
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (error) {
|
|
||||||
|
|
||||||
case ENXIO:
|
|
||||||
printf("device bad\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EFAULT:
|
|
||||||
printf("device not ready\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EINVAL:
|
|
||||||
printf("area improper\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EIO:
|
|
||||||
printf("i/o error\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EINTR:
|
|
||||||
printf("aborted from console\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
printf("succeeded\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("error %d\n", error);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("\n\n");
|
|
||||||
delay(5000000); /* 5 seconds */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the best possible estimate of the time in the timeval
|
* Return the best possible estimate of the time in the timeval
|
||||||
* to which tvp points. We do this by returning the current time
|
* to which tvp points. We do this by returning the current time
|
||||||
|
@ -1088,9 +1199,10 @@ getenvvars(flag, buf)
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
extern u_long bootdev, videobitdepth, videosize;
|
extern u_long bootdev, videobitdepth, videosize;
|
||||||
extern u_long end, esym;
|
extern u_long esym;
|
||||||
extern u_long macos_boottime, MacOSROMBase;
|
extern u_long macos_boottime, MacOSROMBase;
|
||||||
extern long macos_gmtbias;
|
extern long macos_gmtbias;
|
||||||
|
extern char end[];
|
||||||
int root_scsi_id;
|
int root_scsi_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1153,7 +1265,7 @@ getenvvars(flag, buf)
|
||||||
#ifndef SYMTAB_SPACE
|
#ifndef SYMTAB_SPACE
|
||||||
if (esym == 0)
|
if (esym == 0)
|
||||||
#endif
|
#endif
|
||||||
esym = (long) &end;
|
esym = (u_int32_t)end;
|
||||||
|
|
||||||
/* Get MacOS time */
|
/* Get MacOS time */
|
||||||
macos_boottime = getenv("BOOTTIME");
|
macos_boottime = getenv("BOOTTIME");
|
||||||
|
|
Loading…
Reference in New Issue