Added an ELF64 version of preloaded_image.
* There is now 2 structures, preloaded_elf32_image and preloaded_elf64_image, which both inherit from preloaded_image. * For now I've just hardcoded in use of preloaded_elf32_image, but the bootloader ELF code will shortly be converted to use templates which use the appropriate structure. The kernel will be changed later when I add ELF64 support to it. * All kernel_args data is now compatible between 32-bit and 64-bit kernels.
This commit is contained in:
@@ -15,9 +15,9 @@ extern "C" {
|
|||||||
|
|
||||||
/* ELF support */
|
/* ELF support */
|
||||||
|
|
||||||
extern status_t boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
extern status_t boot_arch_elf_relocate_rel(preloaded_elf32_image *image,
|
||||||
struct Elf32_Rel *rel, int rel_len);
|
struct Elf32_Rel *rel, int rel_len);
|
||||||
extern status_t boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
extern status_t boot_arch_elf_relocate_rela(preloaded_elf32_image *image,
|
||||||
struct Elf32_Rela *rel, int rel_len);
|
struct Elf32_Rela *rel, int rel_len);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,27 +11,29 @@
|
|||||||
#include <elf_priv.h>
|
#include <elf_priv.h>
|
||||||
#include <util/FixedWidthPointer.h>
|
#include <util/FixedWidthPointer.h>
|
||||||
|
|
||||||
|
typedef struct elf32_region {
|
||||||
|
area_id id;
|
||||||
|
uint32 start;
|
||||||
|
uint32 size;
|
||||||
|
int32 delta;
|
||||||
|
} _PACKED elf32_region;
|
||||||
|
|
||||||
|
typedef struct elf64_region {
|
||||||
|
area_id id;
|
||||||
|
uint64 start;
|
||||||
|
uint64 size;
|
||||||
|
int64 delta;
|
||||||
|
} _PACKED elf64_region;
|
||||||
|
|
||||||
struct preloaded_image {
|
struct preloaded_image {
|
||||||
FixedWidthPointer<struct preloaded_image> next;
|
FixedWidthPointer<struct preloaded_image> next;
|
||||||
char *name;
|
FixedWidthPointer<char> name;
|
||||||
elf_region text_region;
|
uint8 elf_class;
|
||||||
elf_region data_region;
|
|
||||||
addr_range dynamic_section;
|
addr_range dynamic_section;
|
||||||
struct Elf32_Ehdr elf_header;
|
|
||||||
|
|
||||||
struct Elf32_Sym *syms;
|
FixedWidthPointer<const char> debug_string_table;
|
||||||
struct Elf32_Rel *rel;
|
uint32 num_debug_symbols;
|
||||||
int rel_len;
|
uint32 debug_string_table_size;
|
||||||
struct Elf32_Rela *rela;
|
|
||||||
int rela_len;
|
|
||||||
struct Elf32_Rel *pltrel;
|
|
||||||
int pltrel_len;
|
|
||||||
int pltrel_type;
|
|
||||||
|
|
||||||
struct Elf32_Sym *debug_symbols;
|
|
||||||
const char *debug_string_table;
|
|
||||||
uint32 num_debug_symbols, debug_string_table_size;
|
|
||||||
|
|
||||||
ino_t inode;
|
ino_t inode;
|
||||||
image_id id;
|
image_id id;
|
||||||
@@ -40,11 +42,45 @@ struct preloaded_image {
|
|||||||
// set by the module initialization code
|
// set by the module initialization code
|
||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
|
struct preloaded_elf32_image : public preloaded_image {
|
||||||
|
Elf32_Ehdr elf_header;
|
||||||
|
elf32_region text_region;
|
||||||
|
elf32_region data_region;
|
||||||
|
|
||||||
|
FixedWidthPointer<Elf32_Sym> syms;
|
||||||
|
FixedWidthPointer<Elf32_Rel> rel;
|
||||||
|
int32 rel_len;
|
||||||
|
FixedWidthPointer<Elf32_Rela> rela;
|
||||||
|
int32 rela_len;
|
||||||
|
FixedWidthPointer<Elf32_Rel> pltrel;
|
||||||
|
int32 pltrel_len;
|
||||||
|
int32 pltrel_type;
|
||||||
|
|
||||||
|
FixedWidthPointer<Elf32_Sym> debug_symbols;
|
||||||
|
} _PACKED;
|
||||||
|
|
||||||
|
struct preloaded_elf64_image : public preloaded_image {
|
||||||
|
Elf64_Ehdr elf_header;
|
||||||
|
elf64_region text_region;
|
||||||
|
elf64_region data_region;
|
||||||
|
|
||||||
|
FixedWidthPointer<Elf64_Sym> syms;
|
||||||
|
FixedWidthPointer<Elf64_Rel> rel;
|
||||||
|
int64 rel_len;
|
||||||
|
FixedWidthPointer<Elf64_Rela> rela;
|
||||||
|
int64 rela_len;
|
||||||
|
FixedWidthPointer<Elf64_Rel> pltrel;
|
||||||
|
int64 pltrel_len;
|
||||||
|
int64 pltrel_type;
|
||||||
|
|
||||||
|
FixedWidthPointer<Elf64_Sym> debug_symbols;
|
||||||
|
} _PACKED;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern status_t boot_elf_resolve_symbol(struct preloaded_image *image,
|
extern status_t boot_elf_resolve_symbol(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Sym *symbol, addr_t *symbolAddress);
|
struct Elf32_Sym *symbol, addr_t *symbolAddress);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ typedef struct kernel_args {
|
|||||||
uint32 kernel_args_size;
|
uint32 kernel_args_size;
|
||||||
uint32 version;
|
uint32 version;
|
||||||
|
|
||||||
struct preloaded_image kernel_image;
|
FixedWidthPointer<struct preloaded_image> kernel_image;
|
||||||
FixedWidthPointer<struct preloaded_image> preloaded_images;
|
FixedWidthPointer<struct preloaded_image> preloaded_images;
|
||||||
|
|
||||||
uint32 num_physical_memory_ranges;
|
uint32 num_physical_memory_ranges;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <elf32.h>
|
#include <elf32.h>
|
||||||
|
#include <elf64.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ UsePrivateHeaders shared storage ;
|
|||||||
{
|
{
|
||||||
defines +=
|
defines +=
|
||||||
ALTERNATE_BOOT_ARCH=\\\"x86_64\\\"
|
ALTERNATE_BOOT_ARCH=\\\"x86_64\\\"
|
||||||
|
BOOT_SUPPORT_ELF64
|
||||||
|
|
||||||
BOOT_SUPPORT_PARTITION_EFI
|
BOOT_SUPPORT_PARTITION_EFI
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ UsePrivateHeaders shared storage ;
|
|||||||
{
|
{
|
||||||
defines +=
|
defines +=
|
||||||
ALTERNATE_BOOT_ARCH=\\\"x86\\\"
|
ALTERNATE_BOOT_ARCH=\\\"x86\\\"
|
||||||
|
BOOT_SUPPORT_ELF64
|
||||||
|
|
||||||
BOOT_SUPPORT_PARTITION_EFI
|
BOOT_SUPPORT_PARTITION_EFI
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
|
* Copyright 2012, Alex Smith, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ verify_elf_header(struct Elf32_Ehdr &header)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
elf_parse_dynamic_section(struct preloaded_image *image)
|
elf_parse_dynamic_section(preloaded_elf32_image *image)
|
||||||
{
|
{
|
||||||
image->syms = 0;
|
image->syms = 0;
|
||||||
image->rel = 0;
|
image->rel = 0;
|
||||||
@@ -124,7 +125,7 @@ elf_parse_dynamic_section(struct preloaded_image *image)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
load_elf_symbol_table(int fd, preloaded_image *image)
|
load_elf_symbol_table(int fd, preloaded_elf32_image *image)
|
||||||
{
|
{
|
||||||
struct Elf32_Ehdr &elfHeader = image->elf_header;
|
struct Elf32_Ehdr &elfHeader = image->elf_header;
|
||||||
Elf32_Sym *symbolTable = NULL;
|
Elf32_Sym *symbolTable = NULL;
|
||||||
@@ -226,28 +227,40 @@ error1:
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
elf_load_image(int fd, preloaded_image *image)
|
elf_load_image(int fd, preloaded_image **_image)
|
||||||
{
|
{
|
||||||
size_t totalSize;
|
size_t totalSize;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
TRACE(("elf_load_image(fd = %d, image = %p)\n", fd, image));
|
TRACE(("elf_load_image(fd = %d, _image = %p)\n", fd, _image));
|
||||||
|
|
||||||
|
preloaded_elf32_image *image = (preloaded_elf32_image *)kernel_args_malloc(
|
||||||
|
sizeof(preloaded_elf32_image));
|
||||||
|
if (image == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
struct Elf32_Ehdr &elfHeader = image->elf_header;
|
struct Elf32_Ehdr &elfHeader = image->elf_header;
|
||||||
|
|
||||||
ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr));
|
ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr));
|
||||||
if (length < (ssize_t)sizeof(Elf32_Ehdr))
|
if (length < (ssize_t)sizeof(Elf32_Ehdr)) {
|
||||||
|
kernel_args_free(image);
|
||||||
return B_BAD_TYPE;
|
return B_BAD_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
status = verify_elf_header(elfHeader);
|
status = verify_elf_header(elfHeader);
|
||||||
if (status < B_OK)
|
if (status < B_OK) {
|
||||||
|
kernel_args_free(image);
|
||||||
return status;
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
image->elf_class = elfHeader.e_ident[EI_CLASS];
|
||||||
|
|
||||||
ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize;
|
ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize;
|
||||||
Elf32_Phdr *programHeaders = (struct Elf32_Phdr *)malloc(size);
|
Elf32_Phdr *programHeaders = (struct Elf32_Phdr *)malloc(size);
|
||||||
if (programHeaders == NULL) {
|
if (programHeaders == NULL) {
|
||||||
dprintf("error allocating space for program headers\n");
|
dprintf("error allocating space for program headers\n");
|
||||||
return B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = read_pos(fd, elfHeader.e_phoff, programHeaders, size);
|
length = read_pos(fd, elfHeader.e_phoff, programHeaders, size);
|
||||||
@@ -281,7 +294,7 @@ elf_load_image(int fd, preloaded_image *image)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
elf_region *region;
|
elf32_region *region;
|
||||||
if (header.IsReadWrite()) {
|
if (header.IsReadWrite()) {
|
||||||
if (image->data_region.size != 0) {
|
if (image->data_region.size != 0) {
|
||||||
dprintf("elf: rw already handled!\n");
|
dprintf("elf: rw already handled!\n");
|
||||||
@@ -302,7 +315,7 @@ elf_load_image(int fd, preloaded_image *image)
|
|||||||
B_PAGE_SIZE);
|
B_PAGE_SIZE);
|
||||||
region->delta = -region->start;
|
region->delta = -region->start;
|
||||||
|
|
||||||
TRACE(("segment %d: start = %p, size = %lu, delta = %lx\n", i,
|
TRACE(("segment %ld: start = 0x%lx, size = %lu, delta = %lx\n", i,
|
||||||
region->start, region->size, region->delta));
|
region->start, region->size, region->delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,8 +327,8 @@ elf_load_image(int fd, preloaded_image *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the segment order
|
// get the segment order
|
||||||
elf_region *firstRegion;
|
elf32_region *firstRegion;
|
||||||
elf_region *secondRegion;
|
elf32_region *secondRegion;
|
||||||
if (image->text_region.start < image->data_region.start) {
|
if (image->text_region.start < image->data_region.start) {
|
||||||
firstRegion = &image->text_region;
|
firstRegion = &image->text_region;
|
||||||
secondRegion = &image->data_region;
|
secondRegion = &image->data_region;
|
||||||
@@ -356,7 +369,7 @@ elf_load_image(int fd, preloaded_image *image)
|
|||||||
if (header.p_type != PT_LOAD)
|
if (header.p_type != PT_LOAD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
elf_region *region;
|
elf32_region *region;
|
||||||
if (header.IsReadWrite())
|
if (header.IsReadWrite())
|
||||||
region = &image->data_region;
|
region = &image->data_region;
|
||||||
else if (header.IsExecutable())
|
else if (header.IsExecutable())
|
||||||
@@ -397,6 +410,7 @@ elf_load_image(int fd, preloaded_image *image)
|
|||||||
|
|
||||||
free(programHeaders);
|
free(programHeaders);
|
||||||
|
|
||||||
|
*_image = image;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
error2:
|
error2:
|
||||||
@@ -404,6 +418,7 @@ error2:
|
|||||||
platform_free_region((void *)image->text_region.start, totalSize);
|
platform_free_region((void *)image->text_region.start, totalSize);
|
||||||
error1:
|
error1:
|
||||||
free(programHeaders);
|
free(programHeaders);
|
||||||
|
kernel_args_free(image);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -437,13 +452,7 @@ elf_load_image(Directory *directory, const char *path)
|
|||||||
|
|
||||||
// we still need to load it, so do it
|
// we still need to load it, so do it
|
||||||
|
|
||||||
image = (preloaded_image *)kernel_args_malloc(sizeof(preloaded_image));
|
status_t status = elf_load_image(fd, &image);
|
||||||
if (image == NULL) {
|
|
||||||
close(fd);
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t status = elf_load_image(fd, image);
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
image->name = kernel_args_strdup(path);
|
image->name = kernel_args_strdup(path);
|
||||||
image->inode = stat.st_ino;
|
image->inode = stat.st_ino;
|
||||||
@@ -460,8 +469,10 @@ elf_load_image(Directory *directory, const char *path)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
elf_relocate_image(struct preloaded_image *image)
|
elf_relocate_image(preloaded_image *_image)
|
||||||
{
|
{
|
||||||
|
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(_image);
|
||||||
|
|
||||||
status_t status = elf_parse_dynamic_section(image);
|
status_t status = elf_parse_dynamic_section(image);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
@@ -480,12 +491,13 @@ elf_relocate_image(struct preloaded_image *image)
|
|||||||
TRACE(("total %i plt-relocs\n",
|
TRACE(("total %i plt-relocs\n",
|
||||||
image->pltrel_len / (int)sizeof(struct Elf32_Rel)));
|
image->pltrel_len / (int)sizeof(struct Elf32_Rel)));
|
||||||
|
|
||||||
|
struct Elf32_Rel *pltrel = image->pltrel;
|
||||||
if (image->pltrel_type == DT_REL) {
|
if (image->pltrel_type == DT_REL) {
|
||||||
status = boot_arch_elf_relocate_rel(image, image->pltrel,
|
status = boot_arch_elf_relocate_rel(image, pltrel,
|
||||||
image->pltrel_len);
|
image->pltrel_len);
|
||||||
} else {
|
} else {
|
||||||
status = boot_arch_elf_relocate_rela(image,
|
status = boot_arch_elf_relocate_rela(image,
|
||||||
(struct Elf32_Rela *)image->pltrel, image->pltrel_len);
|
(struct Elf32_Rela *)pltrel, image->pltrel_len);
|
||||||
}
|
}
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
@@ -505,7 +517,7 @@ elf_relocate_image(struct preloaded_image *image)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
boot_elf_resolve_symbol(struct preloaded_image *image,
|
boot_elf_resolve_symbol(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Sym *symbol, addr_t *symbolAddress)
|
struct Elf32_Sym *symbol, addr_t *symbolAddress)
|
||||||
{
|
{
|
||||||
switch (symbol->st_shndx) {
|
switch (symbol->st_shndx) {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
extern void elf_init();
|
extern void elf_init();
|
||||||
extern status_t elf_load_image(Directory *directory, const char *path);
|
extern status_t elf_load_image(Directory *directory, const char *path);
|
||||||
extern status_t elf_load_image(int fd, preloaded_image *image);
|
extern status_t elf_load_image(int fd, preloaded_image **_image);
|
||||||
|
|
||||||
extern status_t elf_relocate_image(struct preloaded_image *image);
|
extern status_t elf_relocate_image(preloaded_image *image);
|
||||||
|
|
||||||
#endif /* LOADER_ELF_H */
|
#endif /* LOADER_ELF_H */
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ load_kernel(stage2_args *args, Directory *volume)
|
|||||||
dprintf("load kernel %s...\n", name);
|
dprintf("load kernel %s...\n", name);
|
||||||
|
|
||||||
elf_init();
|
elf_init();
|
||||||
status_t status = elf_load_image(fd, &gKernelArgs.kernel_image);
|
preloaded_image *image;
|
||||||
|
status_t status = elf_load_image(fd, &image);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@@ -102,13 +103,15 @@ load_kernel(stage2_args *args, Directory *volume)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = elf_relocate_image(&gKernelArgs.kernel_image);
|
gKernelArgs.kernel_image = image;
|
||||||
|
|
||||||
|
status = elf_relocate_image(gKernelArgs.kernel_image);
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
dprintf("relocating kernel failed: %lx!\n", status);
|
dprintf("relocating kernel failed: %lx!\n", status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
gKernelArgs.kernel_image.name = kernel_args_strdup(name);
|
gKernelArgs.kernel_image->name = kernel_args_strdup(name);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ platform_start_kernel(void)
|
|||||||
addr_t stackTop
|
addr_t stackTop
|
||||||
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
||||||
|
|
||||||
|
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
|
||||||
|
(void *)gKernelArgs.kernel_image);
|
||||||
|
|
||||||
//smp_init_other_cpus();
|
//smp_init_other_cpus();
|
||||||
//serial_cleanup();
|
//serial_cleanup();
|
||||||
mmu_init_for_kernel();
|
mmu_init_for_kernel();
|
||||||
@@ -81,8 +84,7 @@ platform_start_kernel(void)
|
|||||||
|
|
||||||
#warning M68K: stop ints
|
#warning M68K: stop ints
|
||||||
|
|
||||||
dprintf("kernel entry at %lx\n",
|
dprintf("kernel entry at %lx\n", image->elf_header.e_entry);
|
||||||
gKernelArgs.kernel_image.elf_header.e_entry);
|
|
||||||
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"move.l %0,%%sp; " // move stack out of way
|
"move.l %0,%%sp; " // move stack out of way
|
||||||
@@ -97,7 +99,7 @@ platform_start_kernel(void)
|
|||||||
"move.l #0x0,-(%%sp);" // dummy retval for call to main
|
"move.l #0x0,-(%%sp);" // dummy retval for call to main
|
||||||
"move.l %1,-(%%sp); " // this is the start address
|
"move.l %1,-(%%sp); " // this is the start address
|
||||||
"rts; " // jump.
|
"rts; " // jump.
|
||||||
: : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry));
|
: : "g" (args), "g" (image->elf_header.e_entry));
|
||||||
|
|
||||||
// Huston, we have a problem!
|
// Huston, we have a problem!
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ platform_start_kernel(void)
|
|||||||
addr_t stackTop
|
addr_t stackTop
|
||||||
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
||||||
|
|
||||||
|
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
|
||||||
|
(void *)gKernelArgs.kernel_image);
|
||||||
|
|
||||||
//smp_init_other_cpus();
|
//smp_init_other_cpus();
|
||||||
//serial_cleanup();
|
//serial_cleanup();
|
||||||
mmu_init_for_kernel();
|
mmu_init_for_kernel();
|
||||||
@@ -81,8 +84,7 @@ platform_start_kernel(void)
|
|||||||
|
|
||||||
#warning M68K: stop ints
|
#warning M68K: stop ints
|
||||||
|
|
||||||
dprintf("kernel entry at %lx\n",
|
dprintf("kernel entry at %lx\n", image->elf_header.e_entry);
|
||||||
gKernelArgs.kernel_image.elf_header.e_entry);
|
|
||||||
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"move.l %0,%%sp; " // move stack out of way
|
"move.l %0,%%sp; " // move stack out of way
|
||||||
@@ -97,7 +99,7 @@ platform_start_kernel(void)
|
|||||||
"move.l #0x0,-(%%sp);" // dummy retval for call to main
|
"move.l #0x0,-(%%sp);" // dummy retval for call to main
|
||||||
"move.l %1,-(%%sp); " // this is the start address
|
"move.l %1,-(%%sp); " // this is the start address
|
||||||
"rts; " // jump.
|
"rts; " // jump.
|
||||||
: : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry));
|
: : "g" (args), "g" (image->elf_header.e_entry));
|
||||||
|
|
||||||
// Huston, we have a problem!
|
// Huston, we have a problem!
|
||||||
|
|
||||||
|
|||||||
@@ -356,6 +356,9 @@ smp_cpu_ready(void)
|
|||||||
|
|
||||||
//TRACE(("smp_cpu_ready: entry cpu %ld\n", curr_cpu));
|
//TRACE(("smp_cpu_ready: entry cpu %ld\n", curr_cpu));
|
||||||
|
|
||||||
|
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
|
||||||
|
(void *)gKernelArgs.kernel_image);
|
||||||
|
|
||||||
// Important. Make sure supervisor threads can fault on read only pages...
|
// Important. Make sure supervisor threads can fault on read only pages...
|
||||||
asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1));
|
asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1));
|
||||||
asm("cld");
|
asm("cld");
|
||||||
@@ -381,7 +384,7 @@ smp_cpu_ready(void)
|
|||||||
"pushl %2; " // this is the start address
|
"pushl %2; " // this is the start address
|
||||||
"ret; " // jump.
|
"ret; " // jump.
|
||||||
: : "g" (curr_cpu), "g" (&gKernelArgs),
|
: : "g" (curr_cpu), "g" (&gKernelArgs),
|
||||||
"g" (gKernelArgs.kernel_image.elf_header.e_entry));
|
"g" (image->elf_header.e_entry));
|
||||||
|
|
||||||
// no where to return to
|
// no where to return to
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ platform_start_kernel(void)
|
|||||||
addr_t stackTop
|
addr_t stackTop
|
||||||
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
||||||
|
|
||||||
|
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
|
||||||
|
(void *)gKernelArgs.kernel_image);
|
||||||
|
|
||||||
smp_init_other_cpus();
|
smp_init_other_cpus();
|
||||||
debug_cleanup();
|
debug_cleanup();
|
||||||
mmu_init_for_kernel();
|
mmu_init_for_kernel();
|
||||||
@@ -91,8 +94,7 @@ platform_start_kernel(void)
|
|||||||
|
|
||||||
smp_boot_other_cpus();
|
smp_boot_other_cpus();
|
||||||
|
|
||||||
dprintf("kernel entry at %lx\n",
|
dprintf("kernel entry at %lx\n", image->elf_header.e_entry);
|
||||||
gKernelArgs.kernel_image.elf_header.e_entry);
|
|
||||||
|
|
||||||
asm("movl %0, %%eax; " // move stack out of way
|
asm("movl %0, %%eax; " // move stack out of way
|
||||||
"movl %%eax, %%esp; "
|
"movl %%eax, %%esp; "
|
||||||
@@ -102,7 +104,7 @@ platform_start_kernel(void)
|
|||||||
"pushl $0x0;" // dummy retval for call to main
|
"pushl $0x0;" // dummy retval for call to main
|
||||||
"pushl %1; " // this is the start address
|
"pushl %1; " // this is the start address
|
||||||
"ret; " // jump.
|
"ret; " // jump.
|
||||||
: : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry));
|
: : "g" (args), "g" (image->elf_header.e_entry));
|
||||||
|
|
||||||
panic("kernel returned!\n");
|
panic("kernel returned!\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,10 @@ clear_bss(void)
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
platform_start_kernel(void)
|
platform_start_kernel(void)
|
||||||
{
|
{
|
||||||
addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry;
|
preloaded_elf32_image* image = static_cast<preloaded_elf32_image*>(
|
||||||
|
(void*)gKernelArgs.kernel_image);
|
||||||
|
|
||||||
|
addr_t kernelEntry = image->elf_header.e_entry;
|
||||||
addr_t stackTop = gKernelArgs.cpu_kstack[0].start
|
addr_t stackTop = gKernelArgs.cpu_kstack[0].start
|
||||||
+ gKernelArgs.cpu_kstack[0].size;
|
+ gKernelArgs.cpu_kstack[0].size;
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ determine_machine(void)
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
platform_start_kernel(void)
|
platform_start_kernel(void)
|
||||||
{
|
{
|
||||||
addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry;
|
preloaded_elf32_image* image = static_cast<preloaded_elf32_image*>(
|
||||||
|
(void*)gKernelArgs.kernel_image);
|
||||||
|
|
||||||
|
addr_t kernelEntry = image->elf_header.e_entry;
|
||||||
addr_t stackTop = gKernelArgs.cpu_kstack[0].start
|
addr_t stackTop = gKernelArgs.cpu_kstack[0].start
|
||||||
+ gKernelArgs.cpu_kstack[0].size;
|
+ gKernelArgs.cpu_kstack[0].size;
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,10 @@ abort(void)
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
platform_start_kernel(void)
|
platform_start_kernel(void)
|
||||||
{
|
{
|
||||||
addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry;
|
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
|
||||||
|
(void *)gKernelArgs.kernel_image);
|
||||||
|
|
||||||
|
addr_t kernelEntry = image->elf_header.e_entry;
|
||||||
addr_t stackTop
|
addr_t stackTop
|
||||||
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
|
||||||
|
|
||||||
@@ -99,8 +102,7 @@ platform_start_kernel(void)
|
|||||||
mmu_init_for_kernel();
|
mmu_init_for_kernel();
|
||||||
// smp_boot_other_cpus();
|
// smp_boot_other_cpus();
|
||||||
|
|
||||||
dprintf("kernel entry at %lx\n",
|
dprintf("kernel entry at %lx\n", kernelEntry);
|
||||||
gKernelArgs.kernel_image.elf_header.e_entry);
|
|
||||||
|
|
||||||
status_t error = arch_start_kernel(&gKernelArgs, kernelEntry,
|
status_t error = arch_start_kernel(&gKernelArgs, kernelEntry,
|
||||||
stackTop);
|
stackTop);
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ is_in_image(struct elf_image_info *image, addr_t address)
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rel *rel, int relLength)
|
struct Elf32_Rel *rel, int relLength)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
@@ -308,7 +308,7 @@ write_8_check(addr_t P, Elf32_Word value)
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rela *rel, int rel_len)
|
struct Elf32_Rela *rel, int rel_len)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ static const char *kRelocations[] = {
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rel *rel, int rel_len)
|
struct Elf32_Rel *rel, int rel_len)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
@@ -137,7 +137,7 @@ write_8_check(addr_t P, Elf32_Word value)
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rela *rel, int rel_len)
|
struct Elf32_Rela *rel, int rel_len)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rel *rel, int rel_len)
|
struct Elf32_Rel *rel, int rel_len)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
@@ -83,7 +83,7 @@ write_8_check(addr_t P, Elf32_Word value)
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rela *rel, int rel_len)
|
struct Elf32_Rela *rel, int rel_len)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rel *rel, int rel_len)
|
struct Elf32_Rel *rel, int rel_len)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
@@ -115,7 +115,7 @@ ha(Elf32_Word value)
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rela *rel, int rel_len)
|
struct Elf32_Rela *rel, int rel_len)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ is_in_image(struct elf_image_info *image, addr_t address)
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rel(struct preloaded_image *image,
|
boot_arch_elf_relocate_rel(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rel *rel, int relLength)
|
struct Elf32_Rel *rel, int relLength)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
@@ -167,7 +167,7 @@ arch_elf_relocate_rel(struct elf_image_info *image,
|
|||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
status_t
|
status_t
|
||||||
boot_arch_elf_relocate_rela(struct preloaded_image *image,
|
boot_arch_elf_relocate_rela(struct preloaded_elf32_image *image,
|
||||||
struct Elf32_Rela *rel, int relLength)
|
struct Elf32_Rela *rel, int relLength)
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -1418,7 +1418,7 @@ legacy_driver_add_preloaded(kernel_args* args)
|
|||||||
status = add_driver(imagePath.Path(), image->id);
|
status = add_driver(imagePath.Path(), image->id);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf("legacy_driver_add_preloaded: Failed to add \"%s\": %s\n",
|
dprintf("legacy_driver_add_preloaded: Failed to add \"%s\": %s\n",
|
||||||
image->name, strerror(status));
|
(char *)image->name, strerror(status));
|
||||||
unload_kernel_add_on(image->id);
|
unload_kernel_add_on(image->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1245,7 +1245,7 @@ error1:
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
insert_preloaded_image(struct preloaded_image *preloadedImage, bool kernel)
|
insert_preloaded_image(struct preloaded_elf32_image *preloadedImage, bool kernel)
|
||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
@@ -1260,8 +1260,14 @@ insert_preloaded_image(struct preloaded_image *preloadedImage, bool kernel)
|
|||||||
image->name = strdup(preloadedImage->name);
|
image->name = strdup(preloadedImage->name);
|
||||||
image->dynamic_section = preloadedImage->dynamic_section.start;
|
image->dynamic_section = preloadedImage->dynamic_section.start;
|
||||||
|
|
||||||
image->text_region = preloadedImage->text_region;
|
image->text_region.id = preloadedImage->text_region.id;
|
||||||
image->data_region = preloadedImage->data_region;
|
image->text_region.start = preloadedImage->text_region.start;
|
||||||
|
image->text_region.size = preloadedImage->text_region.size;
|
||||||
|
image->text_region.delta = preloadedImage->text_region.delta;
|
||||||
|
image->data_region.id = preloadedImage->data_region.id;
|
||||||
|
image->data_region.start = preloadedImage->data_region.start;
|
||||||
|
image->data_region.size = preloadedImage->data_region.size;
|
||||||
|
image->data_region.delta = preloadedImage->data_region.delta;
|
||||||
|
|
||||||
status = elf_parse_dynamic_section(image);
|
status = elf_parse_dynamic_section(image);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
@@ -2468,12 +2474,15 @@ elf_init(kernel_args *args)
|
|||||||
|
|
||||||
// Build a image structure for the kernel, which has already been loaded.
|
// Build a image structure for the kernel, which has already been loaded.
|
||||||
// The preloaded_images were already prepared by the VM.
|
// The preloaded_images were already prepared by the VM.
|
||||||
if (insert_preloaded_image(&args->kernel_image, true) < B_OK)
|
image = args->kernel_image;
|
||||||
|
if (insert_preloaded_image(static_cast<struct preloaded_elf32_image *>(
|
||||||
|
image), true) < B_OK)
|
||||||
panic("could not create kernel image.\n");
|
panic("could not create kernel image.\n");
|
||||||
|
|
||||||
// Build image structures for all preloaded images.
|
// Build image structures for all preloaded images.
|
||||||
for (image = args->preloaded_images; image != NULL; image = image->next)
|
for (image = args->preloaded_images; image != NULL; image = image->next)
|
||||||
insert_preloaded_image(image, false);
|
insert_preloaded_image(static_cast<struct preloaded_elf32_image *>(
|
||||||
|
image), false);
|
||||||
|
|
||||||
add_debugger_command("ls", &dump_address_info,
|
add_debugger_command("ls", &dump_address_info,
|
||||||
"lookup symbol for a particular address");
|
"lookup symbol for a particular address");
|
||||||
@@ -2589,4 +2598,4 @@ _user_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable,
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1805,7 +1805,7 @@ module_init(kernel_args* args)
|
|||||||
for (image = args->preloaded_images; image != NULL; image = image->next) {
|
for (image = args->preloaded_images; image != NULL; image = image->next) {
|
||||||
status_t status = register_preloaded_module_image(image);
|
status_t status = register_preloaded_module_image(image);
|
||||||
if (status != B_OK && image->is_module) {
|
if (status != B_OK && image->is_module) {
|
||||||
dprintf("Could not register image \"%s\": %s\n", image->name,
|
dprintf("Could not register image \"%s\": %s\n", (char *)image->name,
|
||||||
strerror(status));
|
strerror(status));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3537,9 +3537,13 @@ vm_free_unused_boot_loader_range(addr_t start, addr_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO x86_64: hardcoding elf32 is temporary.
|
||||||
static void
|
static void
|
||||||
create_preloaded_image_areas(struct preloaded_image* image)
|
create_preloaded_image_areas(struct preloaded_elf32_image* image)
|
||||||
{
|
{
|
||||||
|
#ifdef __x86_64__
|
||||||
|
panic("fix this");
|
||||||
|
#else
|
||||||
char name[B_OS_NAME_LENGTH];
|
char name[B_OS_NAME_LENGTH];
|
||||||
void* address;
|
void* address;
|
||||||
int32 length;
|
int32 length;
|
||||||
@@ -3570,6 +3574,7 @@ create_preloaded_image_areas(struct preloaded_image* image)
|
|||||||
image->data_region.id = create_area(name, &address, B_EXACT_ADDRESS,
|
image->data_region.id = create_area(name, &address, B_EXACT_ADDRESS,
|
||||||
PAGE_ALIGN(image->data_region.size), B_ALREADY_WIRED,
|
PAGE_ALIGN(image->data_region.size), B_ALREADY_WIRED,
|
||||||
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3842,11 +3847,13 @@ vm_init(kernel_args* args)
|
|||||||
|
|
||||||
allocate_kernel_args(args);
|
allocate_kernel_args(args);
|
||||||
|
|
||||||
create_preloaded_image_areas(&args->kernel_image);
|
create_preloaded_image_areas(static_cast<struct preloaded_elf32_image*>(
|
||||||
|
(void*)args->kernel_image));
|
||||||
|
|
||||||
// allocate areas for preloaded images
|
// allocate areas for preloaded images
|
||||||
for (image = args->preloaded_images; image != NULL; image = image->next)
|
for (image = args->preloaded_images; image != NULL; image = image->next)
|
||||||
create_preloaded_image_areas(image);
|
create_preloaded_image_areas(
|
||||||
|
static_cast<struct preloaded_elf32_image*>(image));
|
||||||
|
|
||||||
// allocate kernel stacks
|
// allocate kernel stacks
|
||||||
for (i = 0; i < args->num_cpus; i++) {
|
for (i = 0; i < args->num_cpus; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user