Convert the code that fetches bootinfo information and stores it into the

kernel from assembler to C and add several comments to make things clearer.
I've been running with these changes for a couple of months without problems.
This commit is contained in:
jmmv 2006-04-12 13:48:52 +00:00
parent 5124fb547a
commit 9ebb7ae9e0
2 changed files with 124 additions and 83 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.37 2006/02/03 11:08:24 jmmv Exp $ */
/* $NetBSD: locore.S,v 1.38 2006/04/12 13:48:52 jmmv Exp $ */
/*-
* Copyright (c) 1998, 2000, 2004 The NetBSD Foundation, Inc.
@ -95,7 +95,6 @@
#include <machine/segments.h>
#include <machine/specialreg.h>
#include <machine/trap.h>
#include <machine/bootinfo.h>
#if NLAPIC > 0
#include <machine/i82489reg.h>
@ -158,13 +157,9 @@
.data
.globl _C_LABEL(cpu)
.globl _C_LABEL(esym),_C_LABEL(boothowto)
.globl _C_LABEL(bootinfo),_C_LABEL(atdevbase)
#ifdef COMPAT_OLDBOOT
.globl _C_LABEL(bootdev)
#endif
.globl _C_LABEL(esym)
.globl _C_LABEL(atdevbase)
.globl _C_LABEL(proc0paddr),_C_LABEL(PDPpaddr)
.globl _C_LABEL(biosbasemem),_C_LABEL(biosextmem)
.globl _C_LABEL(gdt)
#ifdef I586_CPU
.globl _C_LABEL(idt)
@ -197,20 +192,9 @@ _C_LABEL(lapic_tpr):
_C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486,
# or Pentium, or..
_C_LABEL(esym): .long 0 # ptr to end of syms
_C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual
_C_LABEL(proc0paddr): .long 0
_C_LABEL(PDPpaddr): .long 0 # paddr of PDP, for libkvm
#ifndef REALBASEMEM
_C_LABEL(biosbasemem): .long 0 # base memory reported by BIOS
#else
_C_LABEL(biosbasemem): .long REALBASEMEM
#endif
#ifndef REALEXTMEM
_C_LABEL(biosextmem): .long 0 # extended memory reported by BIOS
#else
_C_LABEL(biosextmem): .long REALEXTMEM
#endif
.space 512
tmpstk:
@ -256,71 +240,21 @@ _C_LABEL(Multiboot_Header):
pushl %ebx # Address of Multiboot information
call _C_LABEL(multiboot_pre_reloc)
addl $4,%esp
jmp 3f
jmp 2f
#endif
1:
/*
* Load parameters from stack
* (howto, [bootdev], bootinfo, esym, basemem, extmem).
* At this point, we know that a NetBSD-specific boot loader
* booted this kernel. The stack carries the following parameters:
* (boothowto, [bootdev], bootinfo, esym, biosbasemem, biosextmem),
* 4 bytes each.
*/
movl 4(%esp),%eax
movl %eax,RELOC(boothowto)
#ifdef COMPAT_OLDBOOT
movl 8(%esp),%eax
movl %eax,RELOC(bootdev)
#endif
movl 12(%esp),%eax
addl $4,%esp # Discard return address to boot loader
call _C_LABEL(native_loader)
addl $24,%esp
testl %eax, %eax
jz 1f
movl (%eax), %ebx /* number of entries */
movl $RELOC(bootinfo), %edi
movl %ebx, (%edi)
addl $4, %edi
2:
testl %ebx, %ebx
jz 1f
addl $4, %eax
movl (%eax), %ecx /* address of entry */
pushl %eax
pushl (%ecx) /* len */
pushl %ecx
pushl %edi
addl (%ecx), %edi /* update dest pointer */
cmpl $_RELOC(_C_LABEL(bootinfo) + BOOTINFO_MAXSIZE), %edi
jg 2f
call _C_LABEL(memcpy)
addl $12, %esp
popl %eax
subl $1, %ebx
jmp 2b
2: /* cleanup for overflow case */
addl $16, %esp
movl $RELOC(bootinfo), %edi
subl %ebx, (%edi) /* correct number of entries */
1:
movl 16(%esp),%eax
testl %eax,%eax
jz 1f
addl $KERNBASE,%eax
1: movl %eax,RELOC(esym)
movl RELOC(biosextmem),%eax
testl %eax,%eax
jnz 1f
movl 20(%esp),%eax
movl %eax,RELOC(biosextmem)
1:
movl RELOC(biosbasemem),%eax
testl %eax,%eax
jnz 1f
movl 24(%esp),%eax
movl %eax,RELOC(biosbasemem)
1:
3:
/* First, reset the PSL. */
pushl $PSL_MBO
popfl

View File

@ -1,12 +1,12 @@
/* $NetBSD: machdep.c,v 1.570 2006/02/03 11:08:24 jmmv Exp $ */
/* $NetBSD: machdep.c,v 1.571 2006/04/12 13:48:52 jmmv Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000, 2004 The NetBSD Foundation, Inc.
* Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
* Simulation Facility, NASA Ames Research Center.
* by Charles M. Hannum, by Jason R. Thorpe of the Numerical Aerospace
* Simulation Facility, NASA Ames Research Center and by Julio M. Merino Vidal.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.570 2006/02/03 11:08:24 jmmv Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.571 2006/04/12 13:48:52 jmmv Exp $");
#include "opt_beep.h"
#include "opt_compat_ibcs2.h"
@ -276,6 +276,114 @@ void add_mem_cluster(uint64_t, uint64_t, uint32_t);
extern int time_adjusted;
struct bootinfo bootinfo;
int *esym;
extern int boothowto;
/* Base memory reported by BIOS. */
#ifndef REALBASEMEM
int biosbasemem = 0;
#else
int biosbasemem = REALBASEMEM;
#endif
/* Extended memory reported by BIOS. */
#ifndef REALEXTMEM
int biosextmem = 0;
#else
int biosextmem = REALEXTMEM;
#endif
/* Representation of the bootinfo structure constructed by a NetBSD native
* boot loader. Only be used by native_loader(). */
struct bootinfo_source {
uint32_t bs_naddrs;
paddr_t bs_addrs[1]; /* Actually longer. */
};
/* Only called by locore.h; no need to be in a header file. */
void native_loader(int, int, struct bootinfo_source *, paddr_t, int, int);
/*
* Called as one of the very first things during system startup (just after
* the boot loader gave control to the kernel image), this routine is in
* charge of retrieving the parameters passed in by the boot loader and
* storing them in the appropriate kernel variables.
*
* WARNING: Because the kernel has not yet relocated itself to KERNBASE,
* special care has to be taken when accessing memory because absolute
* addresses (referring to kernel symbols) do not work. So:
*
* 1) Avoid jumps to absolute addresses (such as gotos and switches).
* 2) To access global variables use their physical address, which
* can be obtained using the RELOC macro.
*/
void
native_loader(int bl_boothowto, int bl_bootdev,
struct bootinfo_source *bl_bootinfo, paddr_t bl_esym,
int bl_biosbasemem, int bl_biosextmem)
{
#define RELOC(type, x) ((type)((vaddr_t)(x) - KERNBASE))
*RELOC(int *, &boothowto) = bl_boothowto;
#ifdef COMPAT_OLDBOOT
/*
* Pre-1.3 boot loaders gave the boot device as a parameter
* (instead of a bootinfo entry).
*/
*RELOC(int *, &bootdev) = bl_bootdev;
#endif
/*
* The boot loader provides a physical, non-relocated address
* for the symbols table's end. We need to convert it to a
* virtual address.
*/
if (bl_esym != 0)
*RELOC(int **, &esym) = (int *)((vaddr_t)bl_esym + KERNBASE);
else
*RELOC(int **, &esym) = 0;
/*
* Copy bootinfo entries (if any) from the boot loader's
* representation to the kernel's bootinfo space.
*/
if (bl_bootinfo != NULL) {
size_t i;
uint8_t *data;
struct bootinfo *bidest;
bidest = RELOC(struct bootinfo *, &bootinfo);
data = &bidest->bi_data[0];
for (i = 0; i < bl_bootinfo->bs_naddrs; i++) {
struct btinfo_common *bc;
bc = (struct btinfo_common *)(bl_bootinfo->bs_addrs[i]);
if ((paddr_t)(data + bc->len) >
(paddr_t)(&bidest->bi_data[0] + BOOTINFO_MAXSIZE))
break;
memcpy(data, bc, bc->len);
data += bc->len;
}
bidest->bi_nentries = i;
}
/*
* Configure biosbasemem and biosextmem only if they were not
* explicitly given during the kernel's build.
*/
if (*RELOC(int *, &biosbasemem) == 0)
*RELOC(int *, &biosbasemem) = bl_biosbasemem;
if (*RELOC(int *, &biosextmem) == 0)
*RELOC(int *, &biosextmem) = bl_biosextmem;
#undef RELOC
}
/*
* Machine-dependent startup code
*/
@ -1869,7 +1977,6 @@ init386(paddr_t first_avail)
#if NKSYMS || defined(DDB) || defined(LKM)
{
extern int end;
extern int *esym;
struct btinfo_symtab *symtab;
#ifdef DDB