From 0ef0e3cfa03381777a38cc9fa4db3e8b19680250 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 30 Apr 2010 12:09:43 +0000 Subject: [PATCH] Map read-only segments over-committing for the relocation. This prevents the kernel from committing memory for all read-only segments until we're done relocating. This allows Haiku to boot on machines with less RAM and swap disabled. At least in qemu I could boot with 100 MB and start WebPositive. Probably fixed #5822. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36552 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/runtime_loader/images.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index 2f1d0a4f3b..853bd0033f 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -354,11 +354,20 @@ map_image(int fd, char const* path, image_t* image, bool fixed) return image->regions[i].id; } } else { + // Map all segments r/w first -- write access might be needed for + // relocations. When we've done with those we change the protection + // of read-only segments back to read-only. We map those segments + // over-committing, since quite likely only a relatively small + // number of pages needs to be touched and we want to avoid a lot + // of memory to be committed for them temporarily, just because we + // have to write map them. + uint32 protection = B_READ_AREA | B_WRITE_AREA + | ((image->regions[i].flags & RFLAG_RW) != 0 + ? 0 : B_OVERCOMMITTING_AREA); image->regions[i].id = _kern_map_file(regionName, (void**)&loadAddress, B_EXACT_ADDRESS, - image->regions[i].vmsize, B_READ_AREA | B_WRITE_AREA, - REGION_PRIVATE_MAP, false, fd, - PAGE_BASE(image->regions[i].fdstart)); + image->regions[i].vmsize, protection, REGION_PRIVATE_MAP, false, + fd, PAGE_BASE(image->regions[i].fdstart)); if (image->regions[i].id < 0) { _kern_unreserve_address_range(reservedAddress, reservedSize);