diff options
Diffstat (limited to 'usr/src/uts/i86pc/os/startup.c')
-rw-r--r-- | usr/src/uts/i86pc/os/startup.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c index ac3538f646..82a0a5bc82 100644 --- a/usr/src/uts/i86pc/os/startup.c +++ b/usr/src/uts/i86pc/os/startup.c @@ -22,6 +22,7 @@ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2013 Joyent, Inc. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. @@ -121,6 +122,7 @@ #include <sys/ddi_periodic.h> #include <sys/systeminfo.h> #include <sys/multiboot.h> +#include <sys/ramdisk.h> #ifdef __xpv @@ -2346,6 +2348,20 @@ pp_in_range(page_t *pp, uint64_t low_addr, uint64_t high_addr) (pp->p_pagenum < btopr(high_addr))); } +static int +pp_in_module(page_t *pp, const rd_existing_t *modranges) +{ + uint_t i; + + for (i = 0; modranges[i].phys != 0; i++) { + if (pp_in_range(pp, modranges[i].phys, + modranges[i].phys + modranges[i].size)) + return (1); + } + + return (0); +} + void release_bootstrap(void) { @@ -2353,10 +2369,40 @@ release_bootstrap(void) page_t *pp; extern void kobj_boot_unmountroot(void); extern dev_t rootdev; + uint_t i; + char propname[32]; + rd_existing_t *modranges; #if !defined(__xpv) pfn_t pfn; #endif + /* + * Save the bootfs module ranges so that we can reserve them below + * for the real bootfs. + */ + modranges = kmem_alloc(sizeof (rd_existing_t) * MAX_BOOT_MODULES, + KM_SLEEP); + for (i = 0; ; i++) { + uint64_t start, size; + + modranges[i].phys = 0; + + (void) snprintf(propname, sizeof (propname), + "module-addr-%u", i); + if (do_bsys_getproplen(NULL, propname) <= 0) + break; + (void) do_bsys_getprop(NULL, propname, &start); + + (void) snprintf(propname, sizeof (propname), + "module-size-%u", i); + if (do_bsys_getproplen(NULL, propname) <= 0) + break; + (void) do_bsys_getprop(NULL, propname, &size); + + modranges[i].phys = start; + modranges[i].size = size; + } + /* unmount boot ramdisk and release kmem usage */ kobj_boot_unmountroot(); @@ -2397,9 +2443,8 @@ release_bootstrap(void) continue; } - if (root_is_ramdisk && pp_in_range(pp, ramdisk_start, - ramdisk_end)) { + ramdisk_end) || pp_in_module(pp, modranges)) { pp->p_next = rd_pages; rd_pages = pp; continue; @@ -2411,6 +2456,8 @@ release_bootstrap(void) } PRM_POINT("Boot pages released"); + kmem_free(modranges, sizeof (rd_existing_t) * 99); + #if !defined(__xpv) /* XXPV -- note this following bunch of code needs to be revisited in Xen 3.0 */ /* |