Changes to kernel_args to make it identical for x86 and x86_64.
* Added a FixedWidthPointer template class which uses 64-bit storage to hold a pointer. This is used in place of raw pointers in kernel_args. * Added __attribute__((packed)) to kernel_args and all structures contained within it. This is necessary due to different alignment behaviour for 32-bit and 64-bit compilation with GCC. * With these changes, kernel_args will now come out the same size for both the x86_64 kernel and the loader, excluding the preloaded_image structure which has not yet been changed. * Tested both an x86 GCC2 and GCC4 build, no problems caused by these changes.
This commit is contained in:
parent
192af9e0af
commit
d8efc6caf6
@ -9,6 +9,10 @@
|
||||
# error This file is included from <boot/kernel_args.h> only
|
||||
#endif
|
||||
|
||||
|
||||
#include <util/FixedWidthPointer.h>
|
||||
|
||||
|
||||
#define MAX_BOOT_PTABLES 4
|
||||
|
||||
#define _PACKED __attribute__((packed))
|
||||
@ -34,14 +38,13 @@ typedef struct {
|
||||
// smp stuff
|
||||
uint32 apic_time_cv_factor; // apic ticks per second
|
||||
uint32 apic_phys;
|
||||
uint32 *apic;
|
||||
FixedWidthPointer<void> apic;
|
||||
uint32 ioapic_phys;
|
||||
uint32 *ioapic;
|
||||
uint32 cpu_apic_id[MAX_BOOT_CPUS];
|
||||
uint32 cpu_apic_version[MAX_BOOT_CPUS];
|
||||
// hpet stuff
|
||||
uint32 hpet_phys;
|
||||
uint32 *hpet;
|
||||
} arch_kernel_args;
|
||||
FixedWidthPointer<void> hpet;
|
||||
} _PACKED arch_kernel_args;
|
||||
|
||||
#endif /* KERNEL_ARCH_x86_KERNEL_ARGS_H */
|
||||
|
@ -13,13 +13,13 @@
|
||||
typedef struct addr_range {
|
||||
uint64 start;
|
||||
uint64 size;
|
||||
} addr_range;
|
||||
} _PACKED addr_range;
|
||||
|
||||
|
||||
typedef struct phys_addr_range {
|
||||
phys_addr_t start;
|
||||
phys_size_t size;
|
||||
} phys_addr_range;
|
||||
} _PACKED phys_addr_range;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -6,11 +6,12 @@
|
||||
#define KERNEL_BOOT_DRIVER_SETTINGS_H
|
||||
|
||||
|
||||
#include <util/FixedWidthPointer.h>
|
||||
#include <util/list.h>
|
||||
|
||||
|
||||
struct driver_settings_file {
|
||||
struct driver_settings_file *next;
|
||||
FixedWidthPointer<struct driver_settings_file> next;
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
char *buffer;
|
||||
size_t size;
|
||||
|
@ -9,10 +9,11 @@
|
||||
#include <boot/addr_range.h>
|
||||
#include <sys/stat.h>
|
||||
#include <elf_priv.h>
|
||||
#include <util/FixedWidthPointer.h>
|
||||
|
||||
|
||||
struct preloaded_image {
|
||||
struct preloaded_image *next;
|
||||
FixedWidthPointer<struct preloaded_image> next;
|
||||
char *name;
|
||||
elf_region text_region;
|
||||
elf_region data_region;
|
||||
@ -37,7 +38,7 @@ struct preloaded_image {
|
||||
// the ID field will be filled out in the kernel
|
||||
bool is_module;
|
||||
// set by the module initialization code
|
||||
};
|
||||
} _PACKED;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include <platform_kernel_args.h>
|
||||
#include <arch_kernel_args.h>
|
||||
|
||||
#include <util/FixedWidthPointer.h>
|
||||
|
||||
|
||||
#define CURRENT_KERNEL_ARGS_VERSION 1
|
||||
#define MAX_KERNEL_ARGS_RANGE 20
|
||||
|
||||
@ -42,7 +45,7 @@ typedef struct kernel_args {
|
||||
uint32 version;
|
||||
|
||||
struct preloaded_image kernel_image;
|
||||
struct preloaded_image *preloaded_images;
|
||||
FixedWidthPointer<struct preloaded_image> preloaded_images;
|
||||
|
||||
uint32 num_physical_memory_ranges;
|
||||
phys_addr_range physical_memory_range[MAX_PHYSICAL_MEMORY_RANGE];
|
||||
@ -58,10 +61,10 @@ typedef struct kernel_args {
|
||||
addr_range cpu_kstack[MAX_BOOT_CPUS];
|
||||
|
||||
// boot volume KMessage data
|
||||
uint64 boot_volume;
|
||||
FixedWidthPointer<void> boot_volume;
|
||||
int32 boot_volume_size;
|
||||
|
||||
struct driver_settings_file *driver_settings;
|
||||
FixedWidthPointer<struct driver_settings_file> driver_settings;
|
||||
|
||||
struct {
|
||||
phys_addr_range physical_buffer;
|
||||
@ -72,12 +75,12 @@ typedef struct kernel_args {
|
||||
bool enabled;
|
||||
} frame_buffer;
|
||||
|
||||
void *vesa_modes;
|
||||
FixedWidthPointer<void> vesa_modes;
|
||||
uint16 vesa_modes_size;
|
||||
uint8 vesa_capabilities;
|
||||
void *edid_info;
|
||||
FixedWidthPointer<void> edid_info;
|
||||
|
||||
void *debug_output;
|
||||
FixedWidthPointer<void> debug_output;
|
||||
uint32 debug_size;
|
||||
bool keep_debug_output_buffer;
|
||||
|
||||
@ -85,8 +88,8 @@ typedef struct kernel_args {
|
||||
arch_kernel_args arch_args;
|
||||
|
||||
// bootsplash data
|
||||
uint8 *boot_splash;
|
||||
FixedWidthPointer<uint8> boot_splash;
|
||||
|
||||
} kernel_args;
|
||||
} _PACKED kernel_args;
|
||||
|
||||
#endif /* KERNEL_BOOT_KERNEL_ARGS_H */
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <arch/x86/apm.h>
|
||||
#include <bios_drive.h>
|
||||
#include <util/FixedWidthPointer.h>
|
||||
|
||||
|
||||
// must match SMP_MAX_CPUS in arch_smp.h
|
||||
@ -25,9 +26,10 @@
|
||||
typedef struct {
|
||||
uint16 serial_base_ports[MAX_SERIAL_PORTS];
|
||||
|
||||
bios_drive *drives; // this does not contain the boot drive
|
||||
FixedWidthPointer<bios_drive> drives;
|
||||
// this does not contain the boot drive
|
||||
|
||||
apm_info apm;
|
||||
} platform_kernel_args;
|
||||
} _PACKED platform_kernel_args;
|
||||
|
||||
#endif /* KERNEL_BOOT_PLATFORM_BIOS_IA32_KERNEL_ARGS_H */
|
||||
|
123
headers/private/kernel/util/FixedWidthPointer.h
Normal file
123
headers/private/kernel/util/FixedWidthPointer.h
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef KERNEL_UTIL_FIXED_WIDTH_POINTER_H
|
||||
#define KERNEL_UTIL_FIXED_WIDTH_POINTER_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
/*!
|
||||
\class FixedWidthPointer
|
||||
\brief Pointer class with fixed size (64-bit) storage.
|
||||
|
||||
This class is a pointer-like class that uses a fixed size 64-bit storage.
|
||||
This is used to make kernel_args compatible (i.e. the same size) for both
|
||||
32-bit and 64-bit kernels.
|
||||
*/
|
||||
template<typename Type>
|
||||
class FixedWidthPointer {
|
||||
public:
|
||||
operator Type*() const
|
||||
{
|
||||
return (Type *)(addr_t)fValue;
|
||||
}
|
||||
|
||||
operator addr_t() const
|
||||
{
|
||||
return (addr_t)fValue;
|
||||
}
|
||||
|
||||
Type &operator*() const
|
||||
{
|
||||
return *(Type *)*this;
|
||||
}
|
||||
|
||||
Type *operator->() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
FixedWidthPointer &operator=(const FixedWidthPointer &p)
|
||||
{
|
||||
fValue = p.fValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FixedWidthPointer &operator=(Type *p)
|
||||
{
|
||||
fValue = (addr_t)p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
Get the 64-bit pointer value.
|
||||
\return Pointer address.
|
||||
*/
|
||||
uint64 Get() const
|
||||
{
|
||||
return fValue;
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the 64-bit pointer value.
|
||||
\param addr New address for the pointer.
|
||||
*/
|
||||
void SetTo(uint64 addr)
|
||||
{
|
||||
fValue = addr;
|
||||
}
|
||||
private:
|
||||
uint64 fValue;
|
||||
} _PACKED;
|
||||
|
||||
|
||||
// Specialization for void pointers, can be converted to another pointer type.
|
||||
template<>
|
||||
class FixedWidthPointer<void> {
|
||||
public:
|
||||
operator void*() const
|
||||
{
|
||||
return (void *)(addr_t)fValue;
|
||||
}
|
||||
|
||||
template<typename OtherType>
|
||||
operator OtherType*() const
|
||||
{
|
||||
return (OtherType *)(addr_t)fValue;
|
||||
}
|
||||
|
||||
operator addr_t() const
|
||||
{
|
||||
return (addr_t)fValue;
|
||||
}
|
||||
|
||||
FixedWidthPointer &operator=(const FixedWidthPointer &p)
|
||||
{
|
||||
fValue = p.fValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FixedWidthPointer &operator=(void *p)
|
||||
{
|
||||
fValue = (addr_t)p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint64 Get() const
|
||||
{
|
||||
return fValue;
|
||||
}
|
||||
|
||||
void SetTo(uint64 addr)
|
||||
{
|
||||
fValue = addr;
|
||||
}
|
||||
private:
|
||||
uint64 fValue;
|
||||
} _PACKED;
|
||||
|
||||
|
||||
#endif /* KERNEL_UTIL_FIXED_WIDTH_POINTER_H */
|
@ -128,7 +128,7 @@ main(stage2_args *args)
|
||||
|
||||
buffer = (void*)(((addr_t)buffer + 3) & ~(addr_t)0x3);
|
||||
memcpy(buffer, gBootVolume.Buffer(), gBootVolume.ContentSize());
|
||||
gKernelArgs.boot_volume = (addr_t)buffer;
|
||||
gKernelArgs.boot_volume = buffer;
|
||||
gKernelArgs.boot_volume_size = gBootVolume.ContentSize();
|
||||
|
||||
// ToDo: cleanup, heap_release() etc.
|
||||
|
@ -162,7 +162,7 @@ debug_cleanup(void)
|
||||
|
||||
if (!gKernelArgs.keep_debug_output_buffer) {
|
||||
gKernelArgs.debug_output = kernel_args_malloc(sBufferPosition);
|
||||
if (gKernelArgs.debug_output != NULL) {
|
||||
if (gKernelArgs.debug_output) {
|
||||
memcpy(gKernelArgs.debug_output, sBuffer, sBufferPosition);
|
||||
gKernelArgs.debug_size = sBufferPosition;
|
||||
}
|
||||
|
@ -50,6 +50,6 @@ hpet_init(void)
|
||||
|
||||
TRACE(("hpet_init: found HPET at %x.\n", hpet->hpet_address.address));
|
||||
gKernelArgs.arch_args.hpet_phys = hpet->hpet_address.address;
|
||||
gKernelArgs.arch_args.hpet = (uint32 *)mmu_map_physical_memory(
|
||||
gKernelArgs.arch_args.hpet = (void *)mmu_map_physical_memory(
|
||||
gKernelArgs.arch_args.hpet_phys, B_PAGE_SIZE, kDefaultPageFlags);
|
||||
}
|
||||
|
@ -60,21 +60,21 @@ static int smp_get_current_cpu(void);
|
||||
static uint32
|
||||
apic_read(uint32 offset)
|
||||
{
|
||||
return *(volatile uint32 *)((uint32)gKernelArgs.arch_args.apic + offset);
|
||||
return *(volatile uint32 *)((addr_t)gKernelArgs.arch_args.apic + offset);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
apic_write(uint32 offset, uint32 data)
|
||||
{
|
||||
*(volatile uint32 *)((uint32)gKernelArgs.arch_args.apic + offset) = data;
|
||||
*(volatile uint32 *)((addr_t)gKernelArgs.arch_args.apic + offset) = data;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
smp_get_current_cpu(void)
|
||||
{
|
||||
if (gKernelArgs.arch_args.apic == NULL)
|
||||
if (!gKernelArgs.arch_args.apic)
|
||||
return 0;
|
||||
|
||||
uint8 apicID = apic_read(APIC_ID) >> 24;
|
||||
@ -451,10 +451,10 @@ smp_init_other_cpus(void)
|
||||
(void *)gKernelArgs.arch_args.ioapic_phys));
|
||||
|
||||
// map in the apic
|
||||
gKernelArgs.arch_args.apic = (uint32 *)mmu_map_physical_memory(
|
||||
gKernelArgs.arch_args.apic = (void *)mmu_map_physical_memory(
|
||||
gKernelArgs.arch_args.apic_phys, B_PAGE_SIZE, kDefaultPageFlags);
|
||||
|
||||
TRACE(("smp: apic (mapped) = %p\n", gKernelArgs.arch_args.apic));
|
||||
TRACE(("smp: apic (mapped) = %p\n", (void *)gKernelArgs.arch_args.apic));
|
||||
|
||||
// calculate how fast the apic timer is
|
||||
calculate_apic_timer_conversion_factor();
|
||||
|
@ -957,7 +957,7 @@ platform_init_video(void)
|
||||
}
|
||||
|
||||
gKernelArgs.edid_info = kernel_args_malloc(sizeof(edid1_info));
|
||||
if (gKernelArgs.edid_info != NULL)
|
||||
if (gKernelArgs.edid_info)
|
||||
memcpy(gKernelArgs.edid_info, &info, sizeof(edid1_info));
|
||||
}
|
||||
|
||||
|
@ -146,12 +146,12 @@ video_display_splash(addr_t frameBuffer)
|
||||
// pointer into the lower half of the icons image data
|
||||
gKernelArgs.boot_splash
|
||||
= (uint8*)kernel_args_malloc(uncompressedSize);
|
||||
if (gKernelArgs.boot_splash == NULL)
|
||||
if (!gKernelArgs.boot_splash)
|
||||
return B_NO_MEMORY;
|
||||
uncompress(kSplashIcons8BitCompressedImage,
|
||||
sizeof(kSplashIcons8BitCompressedImage),
|
||||
gKernelArgs.boot_splash, uncompressedSize);
|
||||
lowerHalfIconImage = gKernelArgs.boot_splash
|
||||
lowerHalfIconImage = (uint8 *)gKernelArgs.boot_splash
|
||||
+ (kSplashIconsWidth * iconsHalfHeight);
|
||||
break;
|
||||
default: // 24bits is assumed here
|
||||
@ -159,12 +159,12 @@ video_display_splash(addr_t frameBuffer)
|
||||
// pointer into the lower half of the icons image data
|
||||
gKernelArgs.boot_splash
|
||||
= (uint8*)kernel_args_malloc(uncompressedSize);
|
||||
if (gKernelArgs.boot_splash == NULL)
|
||||
if (!gKernelArgs.boot_splash)
|
||||
return B_NO_MEMORY;
|
||||
uncompress(kSplashIcons24BitCompressedImage,
|
||||
sizeof(kSplashIcons24BitCompressedImage),
|
||||
gKernelArgs.boot_splash, uncompressedSize);
|
||||
lowerHalfIconImage = gKernelArgs.boot_splash
|
||||
lowerHalfIconImage = (uint8 *)gKernelArgs.boot_splash
|
||||
+ (kSplashIconsWidth * iconsHalfHeight) * 3;
|
||||
break;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ platform_init_video(void)
|
||||
edid_dump(&info);
|
||||
#endif
|
||||
gKernelArgs.edid_info = kernel_args_malloc(sizeof(edid1_info));
|
||||
if (gKernelArgs.edid_info != NULL)
|
||||
if (gKernelArgs.edid_info)
|
||||
memcpy(gKernelArgs.edid_info, &info, sizeof(edid1_info));
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ serial_cleanup(void)
|
||||
return;
|
||||
|
||||
gKernelArgs.debug_output = kernel_args_malloc(sBufferPosition);
|
||||
if (gKernelArgs.debug_output != NULL) {
|
||||
if (gKernelArgs.debug_output) {
|
||||
memcpy(gKernelArgs.debug_output, sBuffer, sBufferPosition);
|
||||
gKernelArgs.debug_size = sBufferPosition;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ apic_disable_local_ints()
|
||||
status_t
|
||||
apic_init(kernel_args *args)
|
||||
{
|
||||
if (args->arch_args.apic == NULL)
|
||||
if (!args->arch_args.apic)
|
||||
return B_NO_INIT;
|
||||
|
||||
sLocalAPIC = args->arch_args.apic;
|
||||
|
@ -650,7 +650,7 @@ ioapic_init(kernel_args* args)
|
||||
&ioapic_end_of_interrupt
|
||||
};
|
||||
|
||||
if (args->arch_args.apic == NULL)
|
||||
if (!args->arch_args.apic)
|
||||
return;
|
||||
|
||||
if (args->arch_args.ioapic_phys == 0) {
|
||||
|
@ -217,7 +217,7 @@ hpet_init(struct kernel_args *args)
|
||||
/* hpet_acpi_probe() through a similar "scan spots" table
|
||||
to that of smp.cpp.
|
||||
Seems to be the most elegant solution right now. */
|
||||
if (args->arch_args.hpet == NULL)
|
||||
if (!args->arch_args.hpet)
|
||||
return B_ERROR;
|
||||
|
||||
if (sHPETRegs == NULL) {
|
||||
|
@ -1401,7 +1401,7 @@ syslog_init_post_vm(struct kernel_args* args)
|
||||
sSyslogMessage->ident[0] = '\0';
|
||||
//strcpy(sSyslogMessage->ident, "KERNEL");
|
||||
|
||||
if (args->debug_output != NULL)
|
||||
if (args->debug_output)
|
||||
syslog_write((const char*)args->debug_output, args->debug_size, false);
|
||||
|
||||
char revisionBuffer[64];
|
||||
@ -1431,7 +1431,7 @@ err1:
|
||||
static status_t
|
||||
syslog_init(struct kernel_args* args)
|
||||
{
|
||||
if (!args->keep_debug_output_buffer || args->debug_output == NULL)
|
||||
if (!args->keep_debug_output_buffer || !args->debug_output)
|
||||
return B_OK;
|
||||
|
||||
sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size,
|
||||
|
@ -442,7 +442,7 @@ frame_buffer_console_init(kernel_args* args)
|
||||
add_boot_item(VESA_MODES_BOOT_INFO, sVesaModes, args->vesa_modes_size);
|
||||
}
|
||||
|
||||
if (args->edid_info != NULL) {
|
||||
if (args->edid_info) {
|
||||
edid1_info* info = (edid1_info*)malloc(sizeof(edid1_info));
|
||||
if (info != NULL) {
|
||||
memcpy(info, args->edid_info, sizeof(edid1_info));
|
||||
|
@ -325,7 +325,7 @@ static status_t
|
||||
get_boot_partitions(kernel_args* args, PartitionStack& partitions)
|
||||
{
|
||||
KMessage bootVolume;
|
||||
bootVolume.SetTo((void *)(addr_t)args->boot_volume, args->boot_volume_size);
|
||||
bootVolume.SetTo(args->boot_volume, args->boot_volume_size);
|
||||
|
||||
dprintf("get_boot_partitions(): boot volume message:\n");
|
||||
bootVolume.Dump(&dprintf);
|
||||
|
Loading…
Reference in New Issue
Block a user