Don't store a KMessage in kernel_args for the boot volume, only the buffer address/size.

Pointers in kernel_args are going to be changed to unconditionally use 64-bit
storage (to make kernel_args compatible with both the x86 and x86_64 kernels).
KMessage stores a pointer to its buffer, however since KMessage is used
outside of the boot code it is undesirable to change it to use 64-bit storage
for the pointer as it may add additional overhead on 32-bit builds. Therefore,
only store the buffer address and size and then construct a KMessage from
those in the kernel.
This commit is contained in:
Alex Smith
2012-06-20 11:53:47 +01:00
parent 7417d5ed8d
commit 93cb9538be
15 changed files with 49 additions and 54 deletions
+3 -3
View File
@@ -18,8 +18,6 @@
#include <platform_kernel_args.h> #include <platform_kernel_args.h>
#include <arch_kernel_args.h> #include <arch_kernel_args.h>
#include <util/KMessage.h>
#define CURRENT_KERNEL_ARGS_VERSION 1 #define CURRENT_KERNEL_ARGS_VERSION 1
#define MAX_KERNEL_ARGS_RANGE 20 #define MAX_KERNEL_ARGS_RANGE 20
@@ -59,7 +57,9 @@ typedef struct kernel_args {
uint32 num_cpus; uint32 num_cpus;
addr_range cpu_kstack[MAX_BOOT_CPUS]; addr_range cpu_kstack[MAX_BOOT_CPUS];
KMessage boot_volume; // boot volume KMessage data
void *boot_volume;
int32 boot_volume_size;
struct driver_settings_file *driver_settings; struct driver_settings_file *driver_settings;
+2
View File
@@ -8,10 +8,12 @@
#include <boot/kernel_args.h> #include <boot/kernel_args.h>
#include <util/KMessage.h>
struct stage2_args; struct stage2_args;
extern struct kernel_args gKernelArgs; extern struct kernel_args gKernelArgs;
extern KMessage gBootVolume;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
+1
View File
@@ -19,6 +19,7 @@
static const size_t kChunkSize = 16 * B_PAGE_SIZE; static const size_t kChunkSize = 16 * B_PAGE_SIZE;
kernel_args gKernelArgs; kernel_args gKernelArgs;
KMessage gBootVolume;
static void* sFirstFree; static void* sFirstFree;
static void* sLast; static void* sLast;
+1 -2
View File
@@ -233,8 +233,7 @@ load_modules(stage2_args *args, Directory *volume)
// and now load all partitioning and file system modules // and now load all partitioning and file system modules
// needed to identify the boot volume // needed to identify the boot volume
if (!gKernelArgs.boot_volume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, if (!gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) {
false)) {
// iterate over the mounted volumes and load their file system // iterate over the mounted volumes and load their file system
Partition *partition; Partition *partition;
if (gRoot->GetPartitionFor(volume, &partition) == B_OK) { if (gRoot->GetPartitionFor(volume, &partition) == B_OK) {
+4 -7
View File
@@ -40,9 +40,6 @@ main(stage2_args *args)
gKernelArgs.keep_debug_output_buffer = true; gKernelArgs.keep_debug_output_buffer = true;
#endif #endif
// construct boot_volume KMessage explicitely
new(&gKernelArgs.boot_volume) KMessage;
add_stage2_driver_settings(args); add_stage2_driver_settings(args);
platform_init_video(); platform_init_video();
@@ -123,16 +120,16 @@ main(stage2_args *args)
// clone the boot_volume KMessage into kernel accessible memory // clone the boot_volume KMessage into kernel accessible memory
// note, that we need to 4 byte align the buffer and thus allocate // note, that we need to 4 byte align the buffer and thus allocate
// 3 more bytes // 3 more bytes
KMessage& bootVolume = gKernelArgs.boot_volume; void* buffer = kernel_args_malloc(gBootVolume.ContentSize() + 3);
void* buffer = kernel_args_malloc(bootVolume.ContentSize() + 3);
if (!buffer) { if (!buffer) {
panic("Could not allocate memory for the boot volume kernel " panic("Could not allocate memory for the boot volume kernel "
"arguments"); "arguments");
} }
buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3); buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3);
memcpy(buffer, bootVolume.Buffer(), bootVolume.ContentSize()); memcpy(buffer, gBootVolume.Buffer(), gBootVolume.ContentSize());
bootVolume.SetTo(buffer, bootVolume.ContentSize()); gKernelArgs.boot_volume = buffer;
gKernelArgs.boot_volume_size = gBootVolume.ContentSize();
// ToDo: cleanup, heap_release() etc. // ToDo: cleanup, heap_release() etc.
platform_start_kernel(); platform_start_kernel();
+2 -2
View File
@@ -481,7 +481,7 @@ user_menu_boot_volume(Menu* menu, MenuItem* item)
bootItem->Select(true); bootItem->Select(true);
bootItem->SetData(item->Data()); bootItem->SetData(item->Data());
gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_USER_SELECTED, true); gBootVolume.SetBool(BOOT_VOLUME_USER_SELECTED, true);
return true; return true;
} }
@@ -712,7 +712,7 @@ add_boot_volume_menu(Directory* bootVolume)
menu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); menu->AddItem(item = new(nothrow) MenuItem("Return to main menu"));
item->SetType(MENU_ITEM_NO_CHOICE); item->SetType(MENU_ITEM_NO_CHOICE);
if (gKernelArgs.boot_volume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) if (gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false))
menu->SetChoiceText("CD-ROM or hard drive"); menu->SetChoiceText("CD-ROM or hard drive");
return menu; return menu;
+4 -4
View File
@@ -268,8 +268,8 @@ Partition::_Mount(file_system_module_info *module, Directory **_fileSystem)
status_t status_t
Partition::Mount(Directory **_fileSystem, bool isBootDevice) Partition::Mount(Directory **_fileSystem, bool isBootDevice)
{ {
if (isBootDevice && gKernelArgs.boot_volume.GetBool( if (isBootDevice && gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE,
BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) { false)) {
return _Mount(&gTarFileSystemModule, _fileSystem); return _Mount(&gTarFileSystemModule, _fileSystem);
} }
@@ -293,8 +293,8 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice)
// if we were not booted from the real boot device, we won't scan // if we were not booted from the real boot device, we won't scan
// the device we were booted from (which is likely to be a slow // the device we were booted from (which is likely to be a slow
// floppy or CD) // floppy or CD)
if (isBootDevice && gKernelArgs.boot_volume.GetBool( if (isBootDevice && gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE,
BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) { false)) {
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
} }
+1 -2
View File
@@ -380,8 +380,7 @@ register_boot_file_system(Directory *volume)
return status; return status;
} }
gKernelArgs.boot_volume.SetInt64(BOOT_VOLUME_PARTITION_OFFSET, gBootVolume.SetInt64(BOOT_VOLUME_PARTITION_OFFSET, partition->offset);
partition->offset);
Node *device = get_node_from(partition->FD()); Node *device = get_node_from(partition->FD());
if (device == NULL) { if (device == NULL) {
@@ -161,8 +161,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
TRACE(("boot drive ID: %x\n", gBootDriveID)); TRACE(("boot drive ID: %x\n", gBootDriveID));
//TODO //TODO
gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootVolume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootedFromImage);
gBootedFromImage);
return B_OK; return B_OK;
} }
@@ -1182,8 +1182,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
} }
TRACE(("boot drive size: %Ld bytes\n", drive->Size())); TRACE(("boot drive size: %Ld bytes\n", drive->Size()));
gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootVolume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootedFromImage);
gBootedFromImage);
return B_OK; return B_OK;
} }
@@ -1232,8 +1231,8 @@ platform_register_boot_device(Node *device)
check_cd_boot(drive); check_cd_boot(drive);
#endif #endif
gKernelArgs.boot_volume.SetInt64("boot drive number", drive->DriveID()); gBootVolume.SetInt64("boot drive number", drive->DriveID());
gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE,
&drive->Identifier(), sizeof(disk_identifier)); &drive->Identifier(), sizeof(disk_identifier));
return B_OK; return B_OK;
@@ -167,7 +167,7 @@ static bool sBlockDevicesAdded = false;
static void static void
check_cd_boot(BIOSDrive *drive) check_cd_boot(BIOSDrive *drive)
{ {
gKernelArgs.boot_volume.SetInt32(BOOT_METHOD, BOOT_METHOD_HARD_DISK); gBootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_HARD_DISK);
if (drive->DriveID() != 0) if (drive->DriveID() != 0)
return; return;
@@ -185,7 +185,7 @@ check_cd_boot(BIOSDrive *drive)
specification_packet *packet = (specification_packet *)kDataSegmentScratch; specification_packet *packet = (specification_packet *)kDataSegmentScratch;
if (packet->media_type != 0) if (packet->media_type != 0)
gKernelArgs.boot_volume.SetInt32(BOOT_METHOD, BOOT_METHOD_CD); gBootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_CD);
#if 0 #if 0
dprintf("got CD boot spec:\n"); dprintf("got CD boot spec:\n");
@@ -841,8 +841,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
} }
TRACE(("boot drive size: %Ld bytes\n", drive->Size())); TRACE(("boot drive size: %Ld bytes\n", drive->Size()));
gKernelArgs.boot_volume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootVolume.SetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, gBootedFromImage);
gBootedFromImage);
return B_OK; return B_OK;
} }
@@ -888,8 +887,8 @@ platform_register_boot_device(Node *device)
check_cd_boot(drive); check_cd_boot(drive);
gKernelArgs.boot_volume.SetInt64("boot drive number", drive->DriveID()); gBootVolume.SetInt64("boot drive number", drive->DriveID());
gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE,
&drive->Identifier(), sizeof(disk_identifier)); &drive->Identifier(), sizeof(disk_identifier));
return B_OK; return B_OK;
+2 -2
View File
@@ -130,8 +130,8 @@ platform_register_boot_device(Node *device)
disk.device_type = UNKNOWN_DEVICE; disk.device_type = UNKNOWN_DEVICE;
disk.device.unknown.size = device->Size(); disk.device.unknown.size = device->Size();
gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, &disk,
&disk, sizeof(disk_identifier)); sizeof(disk_identifier));
return B_OK; return B_OK;
} }
@@ -233,8 +233,8 @@ platform_register_boot_device(Node *device)
disk.device_type = UNKNOWN_DEVICE; disk.device_type = UNKNOWN_DEVICE;
disk.device.unknown.size = device->Size(); disk.device.unknown.size = device->Size();
gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, &disk,
&disk, sizeof(disk_identifier)); sizeof(disk_identifier));
return B_OK; return B_OK;
} }
@@ -152,15 +152,14 @@ platform_register_boot_device(Node *device)
rootPath = fileNameEnd + 1; rootPath = fileNameEnd + 1;
} }
KMessage& bootVolume = gKernelArgs.boot_volume; if (gBootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_NET) != B_OK
if (bootVolume.SetInt32(BOOT_METHOD, BOOT_METHOD_NET) != B_OK || gBootVolume.AddInt64("client MAC",
|| bootVolume.AddInt64("client MAC",
sTFTP.MACAddress().ToUInt64()) != B_OK sTFTP.MACAddress().ToUInt64()) != B_OK
|| bootVolume.AddInt32("client IP", sTFTP.IPAddress()) != B_OK || gBootVolume.AddInt32("client IP", sTFTP.IPAddress()) != B_OK
|| bootVolume.AddInt32("server IP", sTFTP.ServerIPAddress()) != B_OK || gBootVolume.AddInt32("server IP", sTFTP.ServerIPAddress()) != B_OK
|| bootVolume.AddInt32("server port", sTFTP.ServerPort()) != B_OK || gBootVolume.AddInt32("server port", sTFTP.ServerPort()) != B_OK
|| (sTFTP.RootPath() || (sTFTP.RootPath()
&& bootVolume.AddString("net root path", rootPath) && gBootVolume.AddString("net root path", rootPath)
!= B_OK)) { != B_OK)) {
return B_NO_MEMORY; return B_NO_MEMORY;
} }
+12 -11
View File
@@ -54,6 +54,8 @@ static struct {
{NULL} {NULL}
}; };
static int32 sBootMethodType;
// This can be used by other code to see if there is a boot file system already // This can be used by other code to see if there is a boot file system already
dev_t gBootDevice = -1; dev_t gBootDevice = -1;
bool gReadOnlyBootDevice = false; bool gReadOnlyBootDevice = false;
@@ -322,27 +324,28 @@ DiskBootMethod::SortPartitions(KPartition** partitions, int32 count)
static status_t static status_t
get_boot_partitions(kernel_args* args, PartitionStack& partitions) get_boot_partitions(kernel_args* args, PartitionStack& partitions)
{ {
const KMessage& bootVolume = args->boot_volume; KMessage bootVolume;
bootVolume.SetTo(args->boot_volume, args->boot_volume_size);
dprintf("get_boot_partitions(): boot volume message:\n"); dprintf("get_boot_partitions(): boot volume message:\n");
bootVolume.Dump(&dprintf); bootVolume.Dump(&dprintf);
// create boot method // create boot method
int32 bootMethodType = bootVolume.GetInt32(BOOT_METHOD, BOOT_METHOD_DEFAULT); sBootMethodType = bootVolume.GetInt32(BOOT_METHOD, BOOT_METHOD_DEFAULT);
dprintf("get_boot_partitions(): boot method type: %" B_PRId32 "\n", dprintf("get_boot_partitions(): boot method type: %" B_PRId32 "\n",
bootMethodType); sBootMethodType);
BootMethod* bootMethod = NULL; BootMethod* bootMethod = NULL;
switch (bootMethodType) { switch (sBootMethodType) {
case BOOT_METHOD_NET: case BOOT_METHOD_NET:
bootMethod = new(nothrow) NetBootMethod(bootVolume, bootMethodType); bootMethod = new(nothrow) NetBootMethod(bootVolume, sBootMethodType);
break; break;
case BOOT_METHOD_HARD_DISK: case BOOT_METHOD_HARD_DISK:
case BOOT_METHOD_CD: case BOOT_METHOD_CD:
default: default:
bootMethod = new(nothrow) DiskBootMethod(bootVolume, bootMethod = new(nothrow) DiskBootMethod(bootVolume,
bootMethodType); sBootMethodType);
break; break;
} }
@@ -415,7 +418,7 @@ get_boot_partitions(kernel_args* args, PartitionStack& partitions)
// sort partition list (e.g.. when booting from CD, CDs should come first in // sort partition list (e.g.. when booting from CD, CDs should come first in
// the list) // the list)
if (!args->boot_volume.GetBool(BOOT_VOLUME_USER_SELECTED, false)) if (!bootVolume.GetBool(BOOT_VOLUME_USER_SELECTED, false))
bootMethod->SortPartitions(partitions.Array(), partitions.CountItems()); bootMethod->SortPartitions(partitions.Array(), partitions.CountItems());
return B_OK; return B_OK;
@@ -513,10 +516,8 @@ vfs_mount_boot_file_system(kernel_args* args)
// whether the module images the boot loader has pre-loaded are the same as // whether the module images the boot loader has pre-loaded are the same as
// on the boot volume. That is the case when booting from hard disk or CD, // on the boot volume. That is the case when booting from hard disk or CD,
// but not via network. // but not via network.
int32 bootMethodType = args->boot_volume.GetInt32(BOOT_METHOD, bool bootingFromBootLoaderVolume = sBootMethodType == BOOT_METHOD_HARD_DISK
BOOT_METHOD_DEFAULT); || sBootMethodType == BOOT_METHOD_CD;
bool bootingFromBootLoaderVolume = bootMethodType == BOOT_METHOD_HARD_DISK
|| bootMethodType == BOOT_METHOD_CD;
module_init_post_boot_device(bootingFromBootLoaderVolume); module_init_post_boot_device(bootingFromBootLoaderVolume);
file_cache_init_post_boot_device(); file_cache_init_post_boot_device();