switch-coreboot/src/lib/linuxbiosmain.c
Eric W. Biederman 0f7f76fb40 Hopefully this is my last commit of major infrasture changes for a while.
Highlights:
 - elfboot.c Now can load images to the ram location where linuxBIOS is running
 - Added the standalone directory for bootloaders built from the linuxBIOS source

Other things:
- Correctly maode fallback_boot.c conditional
- Added entry32.lds to do the math for segment descriptor table entries
- Merged ldscript.cacheram and ldscript.base
- Moved assembly code to the sections .rom.text and .rom.data
- Modified linuxBIOS so C code completely runs from RAM as the SiS630
  case does
- Updated and commented example config files for the supermicro p4dc6
- Bumped the elfboot loader version to 1.0
- Removed extra carriage returns in dump_northbridge.inc (DOS->UNIX)
- General cleanups to the config of the supermicro p4dc6
2002-01-16 05:54:23 +00:00

191 lines
4.9 KiB
C

/* main.c
Taken from OpenBIOS 0.0.1/boot/boot32/main.c which was in turn taken
from /usr/src/linux/arch/i386/boot/compressed/misc.c
Used for start32, 1/11/2000
James Hendricks, Dale Webster */
/* misc.c
*
* This is a collection of several routines from gzip-1.0.3
* adapted for Linux.
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
* puts by Nick Holloway 1993, better puts by Martin Mares 1995
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/
#include <printk.h>
#include <part/fallback_boot.h>
#include <params.h>
#include <subr.h>
#include <rom/read_bytes.h>
#include <string.h>
#include <stdlib.h>
#include <boot/linuxbios_table.h>
#if USE_ELF_BOOT
#include <boot/elf.h>
#endif
#include "do_inflate.h"
#ifdef USE_TFTP
extern void netboot_init(void);
extern int tftp_init(const char *name);
extern int tftp_fetchone(char *buffer);
#endif
int linuxbiosmain(unsigned long base, unsigned long totalram)
{
unsigned char *empty_zero_page;
unsigned char *cmd_line;
unsigned long initrd_start, initrd_size;
#ifdef USE_TFTP
char buffer[256];
char *bufptr;
int buflen;
#endif /* USE_TFTP */
#if USE_ELF_BOOT
return elfboot(streams, get_lb_mem());
#else /* !ELF_BOOT */
printk_info("\n");
printk_info("Welcome to start32, the open sourced starter.\n");
printk_info("This space will eventually hold more diagnostic information.\n");
printk_info("\n");
printk_info("January 2000, James Hendricks, Dale Webster, and Ron Minnich.\n");
printk_info("Version 0.1\n");
printk_info("\n");
initrd_start = 0;
initrd_size = 0;
#ifdef CMD_LINE
cmd_line = CMD_LINE;
#else
cmd_line = "root=/dev/hda1 single";
#endif /* CMD_LINE */
#ifdef LOADER_SETUP
loader_setup(base,
totalram,
&initrd_start,
&initrd_size,
&cmd_line,
&zkernel_start,
&zkernel_mask);
#endif /* LOADER_SETUP */
post_code(0xf1);
#ifdef PYRO_TEST1
printk_notice( "LiLa loader, press a key to test netboot_init:");
buflen = sizeof(buffer);
ttys0_rx_line(buffer, &buflen);
#endif
#ifdef USE_TFTP
netboot_init();
printk_notice("\nnetboot_init test complete, all is well (I hope!)\n");
#endif /* USE_TFTP */
streams->init();
printk_debug("Gunzip setup\n");
gunzip_setup();
printk_debug("Gunzipping boot code\n");
if (gunzip() != 0) {
printk_notice("gunzip failed\n");
post_code(0xff);
return 0;
}
streams->fini();
post_code(0xf8);
#ifdef TFTP_INITRD
printk_notice("Loading initrd now\n");
buflen = tftp_init("initrd");
printk_notice("TFTP init complete (%d)\n",buflen);
buflen = 512; // I know, not it's purpose,
// but it isn't being used at this point.
bufptr = (char *) initrd_start = 0x0400000;
while (buflen == 512) {
buflen = tftp_fetchone(bufptr);
#ifdef DEBUG_TFTP
printk_spew("Got block, bufptr = %lu, size= %u\n",bufptr, buflen);
#endif
bufptr += buflen;
}
initrd_size = (unsigned long) bufptr - initrd_start;
printk_notice("Initrd loaded\n");
if(tftp_init("cmdline") >=0) {
buflen = tftp_fetchone(buffer);
buffer[buflen] = '\0';
cmd_line=buffer;
}
printk_notice("Booting with command line: %s\n",cmd_line);
#endif /* TFTP_INITRD */
/* parameter passing to linux. You have to get the pointer to the
* empty_zero_page, then fill it in.
*/
/* should we do this in intel_main(). If we did we would have to save it
* maybe -- 0x90000 might get stomped. We do it here as the last step.
*/
/* yes I know we need prototypes -- we'll do it soon */
empty_zero_page = get_empty_zero_page();
init_params(empty_zero_page);
post_code(0xf9);
/* the ram address should be the last mbyte, AFAIK. Subtract one for the
* low 1 MB. So subtract 2K total
*/
set_memory_size(empty_zero_page, 0x3c00, totalram - 2048);
post_code(0xfa);
printk_notice("command line - [%s]\n", cmd_line);
set_command_line(empty_zero_page, cmd_line);
set_root_rdonly(empty_zero_page);
set_display(empty_zero_page, 25, 80);
set_initrd(empty_zero_page, initrd_start, initrd_size);
/* Reset to booting from this image as late as possible */
boot_successful();
printk_debug("Jumping to boot code\n");
post_code(0xfe);
/* there seems to be a bug in gas? it's generating wrong bit-patterns ...
typedef void (*kernel) ();
kernel v;
v = (kernel)KERNEL_START;
v();
*/
/* move 0x90000 to into esi (This is the address of the linux parameter page)
* Linux then copies this page into it's ``empty_zero_page'' so it isn't
* stomped while things are being setup.
* Later the ``empty_zero_page'' is zeroed and used fulfill read demands
* on memory mappings of file holes and the like.
* As of 2.4.0-test4 the linux parameter page isn't hardwired to be
* at 0x90000 anymore.
*/
/* move 0 to ebx. This is for SMP support. Jump to kernel */
__asm__ __volatile__("movl $0x90000, %%esi\n\t"
"movl $0, %%ebx\n\t"
"ljmp $0x10, %0\n\t"
:: "i" (0x100000));
return 0; /* It should not ever return */
#endif /* ELF_BOOT */
}