* The boot loader now replaces the first path component of all path names

passed to the kernel with "boot" instead of the volume name; the kernel
  mounts the boot volume always as "/boot".
* This should fix #2757.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27685 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-09-22 08:58:07 +00:00
parent 80d6ff9e6f
commit 18ee966f0a
3 changed files with 53 additions and 21 deletions

View File

@ -6,15 +6,18 @@
#include "elf.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <boot/arch.h>
#include <boot/platform.h>
#include <boot/stage2.h>
#include <elf32.h>
#include <kernel.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "loader.h"
//#define TRACE_ELF
#ifdef TRACE_ELF
@ -423,10 +426,13 @@ elf_load_image(Directory *directory, const char *path)
status_t status = elf_load_image(fd, image);
if (status == B_OK) {
char tmpPath[B_PATH_NAME_LENGTH];
if (directory->GetPath(path, tmpPath, sizeof(tmpPath)) == B_OK)
image->name = kernel_args_strdup(tmpPath);
else
char tempPath[B_PATH_NAME_LENGTH];
if (directory->GetPath(path, tempPath, sizeof(tempPath)) == B_OK) {
// Replace the first path component with "boot", as the kernel
// will always mount the boot volume there.
to_boot_path(tempPath, sizeof(tempPath));
image->name = kernel_args_strdup(tempPath);
} else
image->name = kernel_args_strdup(path);
image->inode = stat.st_ino;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@ -51,6 +51,31 @@ is_bootable(Directory *volume)
}
/*! Replace the first path component with "boot", as the kernel will always
mount the boot volume there.
*/
void
to_boot_path(char *path, size_t pathSize)
{
const size_t bootLength = strlen("boot");
if (path[0] != '/' || pathSize < bootLength + 1)
return;
char *second = strchr(path + 1, '/');
if (second == NULL)
return;
size_t volumeLength = second - path - 1;
if (volumeLength != bootLength) {
memmove(path + 1 + bootLength, path + 1 + volumeLength,
pathSize - 1 - max_c(volumeLength, bootLength));
}
memcpy(path + 1, "boot", bootLength);
}
status_t
load_kernel(stage2_args *args, Directory *volume)
{
@ -75,10 +100,11 @@ load_kernel(stage2_args *args, Directory *volume)
return status;
}
char tmpPath[B_PATH_NAME_LENGTH];
if (volume->GetPath(KERNEL_PATH, tmpPath, sizeof(tmpPath)) == B_OK)
gKernelArgs.kernel_image.name = kernel_args_strdup(tmpPath);
else
char tempPath[B_PATH_NAME_LENGTH];
if (volume->GetPath(KERNEL_PATH, tempPath, sizeof(tempPath)) == B_OK) {
to_boot_path(tempPath, sizeof(tempPath));
gKernelArgs.kernel_image.name = kernel_args_strdup(tempPath);
} else
gKernelArgs.kernel_image.name = kernel_args_strdup("kernel");
return B_OK;
@ -117,12 +143,11 @@ load_modules_from(Directory *volume, const char *path)
}
/** Loads a module by module name. This basically works in the same
* way as the kernel module loader; it will cut off the last part
* of the module name until it could find a module and loads it.
* It tests both, kernel and user module directories.
*/
/*! Loads a module by module name. This basically works in the same
way as the kernel module loader; it will cut off the last part
of the module name until it could find a module and loads it.
It tests both, kernel and user module directories.
*/
static status_t
load_module(Directory *volume, const char *name)
{

View File

@ -1,7 +1,7 @@
/*
** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
* Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef LOADER_H
#define LOADER_H
@ -10,6 +10,7 @@
extern bool is_bootable(Directory *volume);
extern void to_boot_path(char *path, size_t pathSize);
extern status_t load_kernel(stage2_args *args, Directory *volume);
extern status_t load_modules(stage2_args *args, Directory *volume);