grub/kern/main.c

148 lines
3.9 KiB
C
Raw Normal View History

/* main.c - the kernel main routine */
2002-12-27 08:53:07 +00:00
/*
* PUPA -- Preliminary Universal Programming Architecture for GRUB
* Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <pupa/kernel.h>
#include <pupa/misc.h>
#include <pupa/mm.h>
#include <pupa/symbol.h>
#include <pupa/dl.h>
#include <pupa/term.h>
#include <pupa/rescue.h>
2003-01-17 Yoshinori K. Okuji <okuji@enbug.org> * include/pupa/i386/pc/linux.h: New file. * loader/i386/pc/linux.c: Likewise. * loader/i386/pc/chainloader.c (pupa_chainloader_boot_sector): Removed. (pupa_chainloader_unload): Return PUPA_ERR_NONE. (pupa_rescue_cmd_chainloader): Read the image to 0x7C00 instead of PUPA_CHAINLOADER_BOOT_SECTOR. * kern/i386/pc/startup.S: Include pupa/machine/linux.h. (pupa_linux_prot_size): New variable. (pupa_linux_tmp_addr): Likewise. (pupa_linux_real_addr): Likewise. (pupa_linux_boot_zimage): New function. (pupa_linux_boot_bzimage): Likewise. * kern/i386/pc/init.c (struct mem_region): New structure. (MAX_REGIONS): New macro. (mem_regions): New variable. (num_regions): Likewise. (pupa_os_area_addr): Likewise. (pupa_os_area_size): Likewise. (pupa_lower_mem): Likewise. (pupa_upper_mem): Likewise. (add_mem_region): New function. (compact_mem_regions): Likewise. (pupa_machine_init): Set PUPA_LOWER_MEM and PUPA_UPPER_MEM to the size of the conventional memory and that of so-called upper memory (before the first memory hole). Instead of adding each found region to free memory, use add_mem_region and add them after removing overlaps. Also, add only 1/4 of the upper memory to free memory. The rest is used for loading OS images. Maybe this is ad hoc, but this makes it much easier to relocate OS images when booting. * kern/rescue.c (pupa_rescue_cmd_module): Removed. (pupa_enter_rescue_mode): Don't register initrd and module. * kern/mm.c: Include pupa/dl.h. * kern/main.c: Include pupa/file.h and pupa/device.h. * kern/loader.c (pupa_loader_load_module_func): Removed. (pupa_loader_load_module): Likewise. * kern/dl.c (pupa_dl_load): Use the suffix ``.mod'' instead of ``.o''. * include/pupa/i386/pc/loader.h (pupa_linux_prot_size): Declared. (pupa_linux_tmp_addr): Likewise. (pupa_linux_real_addr): Likewise. (pupa_linux_boot_zimage): Likewise. (pupa_linux_boot_bzimage): Likewise. * include/pupa/i386/pc/init.h (pupa_lower_mem): Declared. (pupa_upper_mem): Likewise. (pupa_gate_a20): Don't export, because turning off Gate A20 in a module is too dangerous. * include/pupa/loader.h (pupa_os_area_addr): Declared. (pupa_os_area_size): Likewise. (pupa_loader_set): Remove the first argument. Loader doesn't manage modules or initrd any longer. (pupa_loader_load_module): Removed. * conf/i386-pc.rmk (pkgdata_MODULES): Added linux.mod. (linux_mod_SOURCES): New variable. (linux_mod_CFLAGS): Likewise.
2003-01-17 02:52:05 +00:00
#include <pupa/file.h>
#include <pupa/device.h>
2002-12-27 08:53:07 +00:00
/* Return the end of the core image. */
pupa_addr_t
pupa_get_end_addr (void)
{
return pupa_total_module_size + pupa_end_addr;
}
/* Load all modules in core. */
static void
pupa_load_modules (void)
{
struct pupa_module_header *header;
for (header = (struct pupa_module_header *) pupa_end_addr;
header < (struct pupa_module_header *) pupa_get_end_addr ();
header = (struct pupa_module_header *) ((char *) header + header->size))
{
if (! pupa_dl_load_core ((char *) header + header->offset,
(header->size - header->offset)))
pupa_fatal ("%s", pupa_errmsg);
}
}
/* Add the region where modules reside into dynamic memory. */
static void
pupa_add_unused_region (void)
{
if (pupa_total_module_size)
pupa_mm_init_region ((void *) pupa_end_addr, pupa_total_module_size);
}
/* Set the root device according to the dl prefix. */
static void
pupa_set_root_dev (void)
{
const char *prefix;
prefix = pupa_dl_get_prefix ();
if (prefix)
{
char *dev;
dev = pupa_file_get_device_name (prefix);
if (dev)
{
pupa_device_set_root (dev);
pupa_free (dev);
}
}
}
/* Load the normal mode module and execute the normal mode if possible. */
static void
pupa_load_normal_mode (void)
{
if (pupa_dl_load ("normal"))
{
void (*normal_func) (const char *config);
/* If the function pupa_enter_normal_mode is present, call it. */
normal_func = pupa_dl_resolve_symbol ("pupa_enter_normal_mode");
if (normal_func)
{
char *config;
char *prefix;
prefix = pupa_dl_get_prefix ();
if (! prefix)
pupa_fatal ("The dl prefix is not set!");
config = pupa_malloc (pupa_strlen (prefix) + sizeof ("/pupa.cfg"));
if (! config)
pupa_fatal ("out of memory");
pupa_sprintf (config, "%s/pupa.cfg", prefix);
(*normal_func) (config);
pupa_free (config);
}
else
pupa_printf ("No entrance routine in the normal mode!\n");
}
else
pupa_printf ("Failed to load the normal mode.\n");
/* Ignore any error, because we have the rescue mode anyway. */
pupa_errno = PUPA_ERR_NONE;
}
2002-12-27 08:53:07 +00:00
/* The main routine. */
void
pupa_main (void)
{
/* First of all, initialize the machine. */
pupa_machine_init ();
/* Hello. */
pupa_setcolorstate (PUPA_TERM_COLOR_HIGHLIGHT);
pupa_printf ("Welcome to PUPA!\n\n");
2002-12-27 08:53:07 +00:00
pupa_setcolorstate (PUPA_TERM_COLOR_STANDARD);
/* It is better to set the root device as soon as possible,
for convenience. */
pupa_set_root_dev ();
/* Load pre-loaded modules and free the space. */
2002-12-27 08:53:07 +00:00
pupa_register_exported_symbols ();
pupa_load_modules ();
pupa_add_unused_region ();
/* Go to the real world. */
pupa_load_normal_mode ();
2002-12-27 08:53:07 +00:00
/* If pupa_enter_normal_mode fails or doesn't exist, enter rescue mode. */
pupa_printf ("Entering into rescue mode...\n");
pupa_enter_rescue_mode ();
}