Revert "loader: load all available file/partitioning system modules."

This reverts commit ce624c696f.
This commit is contained in:
Jessica Hamilton
2019-04-25 05:05:19 +00:00
parent 0e4b529df5
commit 0f00993773
+112 -37
View File
@@ -5,58 +5,61 @@
#include "loader.h" #include "loader.h"
#include "RootFileSystem.h"
#include "elf.h" #include "elf.h"
#include "RootFileSystem.h"
#include <OS.h>
#include <boot/partitions.h>
#include <boot/platform.h>
#include <boot/stage2.h>
#include <boot/stdio.h>
#include <boot/vfs.h>
#include <directories.h> #include <directories.h>
#include <OS.h>
#include <util/list.h> #include <util/list.h>
#include <boot/stage2.h>
#include <boot/vfs.h>
#include <boot/platform.h>
#include <boot/stdio.h>
#include <boot/partitions.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#ifndef BOOT_ARCH #ifndef BOOT_ARCH
#error BOOT_ARCH has to be defined to differentiate the kernel per platform # error BOOT_ARCH has to be defined to differentiate the kernel per platform
#endif #endif
#define SYSTEM_DIRECTORY_PREFIX "system/" #define SYSTEM_DIRECTORY_PREFIX "system/"
#define KERNEL_IMAGE "kernel_" BOOT_ARCH #define KERNEL_IMAGE "kernel_" BOOT_ARCH
#define KERNEL_PATH SYSTEM_DIRECTORY_PREFIX KERNEL_IMAGE #define KERNEL_PATH SYSTEM_DIRECTORY_PREFIX KERNEL_IMAGE
#ifdef ALTERNATE_BOOT_ARCH #ifdef ALTERNATE_BOOT_ARCH
#define ALTERNATE_KERNEL_IMAGE "kernel_" ALTERNATE_BOOT_ARCH # define ALTERNATE_KERNEL_IMAGE "kernel_" ALTERNATE_BOOT_ARCH
#define ALTERNATE_KERNEL_PATH "system/" ALTERNATE_KERNEL_IMAGE # define ALTERNATE_KERNEL_PATH "system/" ALTERNATE_KERNEL_IMAGE
#endif #endif
static const char* const kSystemDirectoryPrefix = SYSTEM_DIRECTORY_PREFIX; static const char* const kSystemDirectoryPrefix = SYSTEM_DIRECTORY_PREFIX;
static const char* sKernelPaths[][2] = { static const char *sKernelPaths[][2] = {
{KERNEL_PATH, KERNEL_IMAGE}, { KERNEL_PATH, KERNEL_IMAGE },
#ifdef ALTERNATE_BOOT_ARCH #ifdef ALTERNATE_BOOT_ARCH
{ALTERNATE_KERNEL_PATH, ALTERNATE_KERNEL_IMAGE}, { ALTERNATE_KERNEL_PATH, ALTERNATE_KERNEL_IMAGE },
#endif #endif
{NULL, NULL}, { NULL, NULL },
}; };
static const char* sAddonPaths[] = {kVolumeLocalSystemKernelAddonsDirectory, static const char *sAddonPaths[] = {
kVolumeLocalSystemKernelAddonsDirectory,
kVolumeLocalCommonNonpackagedKernelAddonsDirectory, kVolumeLocalCommonNonpackagedKernelAddonsDirectory,
kVolumeLocalCommonKernelAddonsDirectory, kVolumeLocalCommonKernelAddonsDirectory,
kVolumeLocalUserNonpackagedKernelAddonsDirectory, kVolumeLocalUserNonpackagedKernelAddonsDirectory,
kVolumeLocalUserKernelAddonsDirectory, NULL}; kVolumeLocalUserKernelAddonsDirectory,
NULL
};
static int static int
open_maybe_packaged(BootVolume& volume, const char* path, int openMode) open_maybe_packaged(BootVolume& volume, const char* path, int openMode)
{ {
if (strncmp(path, kSystemDirectoryPrefix, strlen(kSystemDirectoryPrefix)) if (strncmp(path, kSystemDirectoryPrefix, strlen(kSystemDirectoryPrefix))
== 0) { == 0) {
path += strlen(kSystemDirectoryPrefix); path += strlen(kSystemDirectoryPrefix);
return open_from(volume.SystemDirectory(), path, openMode); return open_from(volume.SystemDirectory(), path, openMode);
} }
@@ -83,7 +86,7 @@ find_kernel(BootVolume& volume, const char** name = NULL)
bool bool
is_bootable(Directory* volume) is_bootable(Directory *volume)
{ {
if (volume->IsEmpty()) if (volume->IsEmpty())
return false; return false;
@@ -106,7 +109,7 @@ is_bootable(Directory* volume)
status_t status_t
load_kernel(stage2_args* args, BootVolume& volume) load_kernel(stage2_args* args, BootVolume& volume)
{ {
const char* name; const char *name;
int fd = find_kernel(volume, &name); int fd = find_kernel(volume, &name);
if (fd < B_OK) if (fd < B_OK)
return fd; return fd;
@@ -114,7 +117,7 @@ load_kernel(stage2_args* args, BootVolume& volume)
dprintf("load kernel %s...\n", name); dprintf("load kernel %s...\n", name);
elf_init(); elf_init();
preloaded_image* image; preloaded_image *image;
status_t status = elf_load_image(fd, &image); status_t status = elf_load_image(fd, &image);
close(fd); close(fd);
@@ -147,11 +150,11 @@ load_modules_from(BootVolume& volume, const char* path)
if (fd < B_OK) if (fd < B_OK)
return fd; return fd;
Directory* modules = (Directory*)get_node_from(fd); Directory *modules = (Directory *)get_node_from(fd);
if (modules == NULL) if (modules == NULL)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
void* cookie; void *cookie;
if (modules->Open(&cookie, O_RDONLY) == B_OK) { if (modules->Open(&cookie, O_RDONLY) == B_OK) {
char name[B_FILE_NAME_LENGTH]; char name[B_FILE_NAME_LENGTH];
while (modules->GetNextEntry(cookie, name, sizeof(name)) == B_OK) { while (modules->GetNextEntry(cookie, name, sizeof(name)) == B_OK) {
@@ -160,8 +163,7 @@ load_modules_from(BootVolume& volume, const char* path)
status_t status = elf_load_image(modules, name); status_t status = elf_load_image(modules, name);
if (status != B_OK) if (status != B_OK)
dprintf("Could not load \"%s\" error %" B_PRIx32 "\n", name, dprintf("Could not load \"%s\" error %" B_PRIx32 "\n", name, status);
status);
} }
modules->Close(cookie); modules->Close(cookie);
@@ -171,13 +173,67 @@ load_modules_from(BootVolume& 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.
*/
static status_t
load_module(BootVolume& volume, const char* name)
{
char moduleName[B_FILE_NAME_LENGTH];
if (strlcpy(moduleName, name, sizeof(moduleName)) > sizeof(moduleName))
return B_NAME_TOO_LONG;
for (int32 i = 0; sAddonPaths[i]; i++) {
// get base path
int baseFD = open_maybe_packaged(volume, sAddonPaths[i], O_RDONLY);
if (baseFD < B_OK)
continue;
Directory *base = (Directory *)get_node_from(baseFD);
if (base == NULL) {
close(baseFD);
continue;
}
while (true) {
int fd = open_from(base, moduleName, O_RDONLY);
if (fd >= B_OK) {
struct stat stat;
if (fstat(fd, &stat) != 0 || !S_ISREG(stat.st_mode))
return B_BAD_VALUE;
status_t status = elf_load_image(base, moduleName);
close(fd);
close(baseFD);
return status;
}
// cut off last name element (or stop trying if there are no more)
char *last = strrchr(moduleName, '/');
if (last != NULL)
last[0] = '\0';
else
break;
}
close(baseFD);
}
return B_OK;
}
status_t status_t
load_modules(stage2_args* args, BootVolume& volume) load_modules(stage2_args* args, BootVolume& volume)
{ {
int32 failed = 0; int32 failed = 0;
// ToDo: this should be mostly replaced by a hardware oriented detection // ToDo: this should be mostly replaced by a hardware oriented detection mechanism
// mechanism
int32 i = 0; int32 i = 0;
for (; sAddonPaths[i]; i++) { for (; sAddonPaths[i]; i++) {
@@ -191,7 +247,7 @@ load_modules(stage2_args* args, BootVolume& volume)
if (failed == i) { if (failed == i) {
// couldn't load any boot modules // couldn't load any boot modules
// fall back to load all modules (currently needed by the boot floppy) // fall back to load all modules (currently needed by the boot floppy)
const char* paths[] = {"bus_managers", "busses/ide", "busses/scsi", const char *paths[] = { "bus_managers", "busses/ide", "busses/scsi",
"generic", "partitioning_systems", "drivers/bin", NULL}; "generic", "partitioning_systems", "drivers/bin", NULL};
for (int32 i = 0; paths[i]; i++) { for (int32 i = 0; paths[i]; i++) {
@@ -202,12 +258,31 @@ load_modules(stage2_args* args, BootVolume& volume)
} }
// and now load all partitioning and file system modules // and now load all partitioning and file system modules
char path[B_FILE_NAME_LENGTH]; // needed to identify the boot volume
snprintf(path, sizeof(path), "%s/%s", sAddonPaths[0], "file_systems");
load_modules_from(volume, path); if (!gBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)
snprintf( && gBootVolume.GetInt32(BOOT_METHOD, BOOT_METHOD_DEFAULT)
path, sizeof(path), "%s/%s", sAddonPaths[0], "partitioning_systems"); != BOOT_METHOD_CD) {
load_modules_from(volume, path); // iterate over the mounted volumes and load their file system
Partition *partition;
if (gRoot->GetPartitionFor(volume.RootDirectory(), &partition)
== B_OK) {
while (partition != NULL) {
load_module(volume, partition->ModuleName());
partition = partition->Parent();
}
}
} else {
// The boot image should only contain the file system
// needed to boot the system, so we just load it.
// ToDo: this is separate from the fall back from above
// as this piece will survive a more intelligent module
// loading approach...
char path[B_FILE_NAME_LENGTH];
snprintf(path, sizeof(path), "%s/%s", sAddonPaths[0], "file_systems");
load_modules_from(volume, path);
}
return B_OK; return B_OK;
} }