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:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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" {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user