diff --git a/ChangeLog b/ChangeLog index dd835ed2e..e6ffba2c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2003-01-07 Yoshinori K. Okuji + + * util/i386/pc/pupa-setup.c (setup): Convert the endianness of + the length of a blocklist correctly. + + * util/i386/pc/biosdisk.c (pupa_util_biosdisk_open) [__linux__]: + Use ioctl only if the OS file is a block device. + (pupa_util_biosdisk_open): Don't use ST.ST_BLOCKS, because it is + not very useful for normal files. + + * kern/main.c (pupa_set_root_dev): New function. + (pupa_load_normal_mode): Likewise. + (pupa_main): Call those above. + + * include/pupa/types.h (pupa_swap_bytes16): Cast the result to + pupa_uint16_t. + + * include/pupa/kernel.h (pupa_enter_normal_mode): Removed. + 2003-01-06 Yoshinori K. Okuji * util/i386/pc/pupa-setup.c: Include pupa/machine/kernel.h. diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 4d5a06c90..2e48c9c69 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -55,7 +55,4 @@ pupa_addr_t pupa_get_end_addr (void); /* Register all the exported symbols. This is automatically generated. */ void pupa_register_exported_symbols (void); -/* Enter normal mode. */ -void pupa_enter_normal_mode (void); - #endif /* ! PUPA_KERNEL_HEADER */ diff --git a/include/grub/types.h b/include/grub/types.h index b2d4482d0..f44618a76 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -85,7 +85,7 @@ typedef pupa_int32_t pupa_ssize_t; #define pupa_swap_bytes16(x) \ ({ \ pupa_uint16_t _x = (x); \ - (_x << 8) | (_x >> 8); \ + (pupa_uint16_t) ((_x << 8) | (_x >> 8)); \ }) #define pupa_swap_bytes32(x) \ diff --git a/kern/main.c b/kern/main.c index 256a084d3..80eb6f7f1 100644 --- a/kern/main.c +++ b/kern/main.c @@ -1,3 +1,4 @@ +/* main.c - the kernel main routine */ /* * PUPA -- Preliminary Universal Programming Architecture for GRUB * Copyright (C) 2002 Yoshinori K. Okuji @@ -56,12 +57,68 @@ pupa_add_unused_region (void) 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) { - void (*normal_func) (void); - /* First of all, initialize the machine. */ pupa_machine_init (); @@ -70,15 +127,18 @@ pupa_main (void) 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 (); - /* If the function pupa_enter_normal_mode is present, call it. */ - normal_func = pupa_dl_resolve_symbol ("pupa_enter_normal_mode"); - if (normal_func) - (*normal_func) (); - + /* 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 (); diff --git a/util/i386/pc/biosdisk.c b/util/i386/pc/biosdisk.c index 9ad1e558b..8d5d8d2e3 100644 --- a/util/i386/pc/biosdisk.c +++ b/util/i386/pc/biosdisk.c @@ -177,6 +177,12 @@ pupa_util_biosdisk_open (const char *name, pupa_disk_t disk) if (! fd) return pupa_error (PUPA_ERR_BAD_DEVICE, "cannot open `%s'", map[drive]); + if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode)) + { + close (fd); + goto fail; + } + if (ioctl (fd, BLKGETSIZE, &nr)) { close (fd); @@ -198,11 +204,7 @@ pupa_util_biosdisk_open (const char *name, pupa_disk_t disk) if (stat (map[drive], &st) < 0) return pupa_error (PUPA_ERR_BAD_DEVICE, "cannot stat `%s'", map[drive]); - if (st.st_blocks) - disk->total_sectors = st.st_blocks; - else - /* Hmm... Use st_size instead. */ - disk->total_sectors = st.st_size >> PUPA_DISK_SECTOR_BITS; + disk->total_sectors = st.st_size >> PUPA_DISK_SECTOR_BITS; pupa_util_info ("the size of %s is %lu", name, disk->total_sectors); diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index cada26e0f..94a9e743a 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -129,7 +129,7 @@ setup (const char *prefix, const char *dir, if (block != first_block && (pupa_le_to_cpu32 (prev->start) + pupa_le_to_cpu16 (prev->len)) == sector) - prev->len = pupa_le_to_cpu16 (prev->len) + 1; + prev->len = pupa_cpu_to_le16 (pupa_le_to_cpu16 (prev->len) + 1); else { block->start = pupa_cpu_to_le32 (sector);