mirror of
https://git.proxmox.com/git/grub2
synced 2025-05-18 02:18:19 +00:00

* 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.
148 lines
3.9 KiB
C
148 lines
3.9 KiB
C
/* main.c - the kernel main routine */
|
|
/*
|
|
* 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>
|
|
#include <pupa/file.h>
|
|
#include <pupa/device.h>
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/* 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");
|
|
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. */
|
|
pupa_register_exported_symbols ();
|
|
pupa_load_modules ();
|
|
pupa_add_unused_region ();
|
|
|
|
/* Go to the real world. */
|
|
pupa_load_normal_mode ();
|
|
|
|
/* If pupa_enter_normal_mode fails or doesn't exist, enter rescue mode. */
|
|
pupa_printf ("Entering into rescue mode...\n");
|
|
pupa_enter_rescue_mode ();
|
|
}
|