From 3243de575048534d0fbcbeec5c4a22acbfb741f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 5 Sep 2010 22:56:22 +0000 Subject: [PATCH] boot_loader_openfirmware: Add iSCSI boot support If no Haiku remote disk server is found, try an iSCSI discovery session on the TFTP server, using the IP address from the boot command or OF options. All available IPv4 targets are considered, Target Portal Groups are ignored. RFC 4173 suggests a mechanism that avoids a discovery session by using DHCP; that requires a compatibly configured DHCP server though and we wouldn't have access to such data currently anyway. iSCSI is currently used as fallback, and when it doesn't succeed it falls back to the menu as before. Resolves ticket #5319. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38537 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../boot/platform/openfirmware/devices.cpp | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/system/boot/platform/openfirmware/devices.cpp b/src/system/boot/platform/openfirmware/devices.cpp index 9e0f5a5f41..03b00bfe4f 100644 --- a/src/system/boot/platform/openfirmware/devices.cpp +++ b/src/system/boot/platform/openfirmware/devices.cpp @@ -1,5 +1,6 @@ /* * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2010, Andreas Färber * All rights reserved. Distributed under the terms of the MIT License. */ @@ -10,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -20,6 +23,9 @@ #include "machine.h" +#define ENABLE_ISCSI + + char sBootPath[192]; @@ -46,14 +52,45 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) status_t error = net_stack_init(); if (error != B_OK) return error; - + + ip_addr_t bootAddress = 0; + char* bootArgs = strrchr(sBootPath, ':'); + if (bootArgs != NULL) { + bootArgs++; + char* comma = strchr(bootArgs, ','); + if (comma != NULL && comma - bootArgs > 0) { + comma[0] = '\0'; + bootAddress = ip_parse_address(bootArgs); + comma[0] = ','; + } + } + if (bootAddress == 0) { + int package = of_finddevice("/options"); + char defaultServerIP[16]; + int bytesRead = of_getprop(package, "default-server-ip", + defaultServerIP, sizeof(defaultServerIP) - 1); + if (bytesRead != OF_FAILED && bytesRead > 1) { + defaultServerIP[bytesRead] = '\0'; + bootAddress = ip_parse_address(defaultServerIP); + } + } + // init a remote disk, if possible RemoteDisk *remoteDisk = RemoteDisk::FindAnyRemoteDisk(); - if (!remoteDisk) - return B_ENTRY_NOT_FOUND; + if (remoteDisk != NULL) { + devicesList->Add(remoteDisk); + return B_OK; + } - devicesList->Add(remoteDisk); - return B_OK; +#ifdef ENABLE_ISCSI + if (bootAddress != 0) { + if (iSCSITarget::DiscoverTargets(bootAddress, ISCSI_PORT, + devicesList)) + return B_OK; + } +#endif + + return B_ENTRY_NOT_FOUND; } if (strcmp("block", type) != 0) {