1 /* 2 * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Copyright 2006, Marcus Overhagen, marcus@overhagen.de. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 #include "bios.h" 8 #include "pxe_undi.h" 9 #include "network.h" 10 11 #include <KernelExport.h> 12 #include <boot/platform.h> 13 #include <boot/vfs.h> 14 #include <boot/stdio.h> 15 #include <boot/stage2.h> 16 #include <boot/net/NetStack.h> 17 #include <boot/net/RemoteDisk.h> 18 #include <util/kernel_cpp.h> 19 20 #include <string.h> 21 22 #define TRACE_DEVICES 23 #ifdef TRACE_DEVICES 24 # define TRACE(x...) dprintf(x) 25 #else 26 # define TRACE(x...) 27 #endif 28 29 30 status_t 31 platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) 32 { 33 TRACE("platform_add_boot_device\n"); 34 35 status_t error = net_stack_init(); 36 if (error != B_OK) 37 return error; 38 39 // init a remote disk, if possible 40 RemoteDisk *remoteDisk = RemoteDisk::FindAnyRemoteDisk(); 41 if (!remoteDisk) { 42 unsigned ip = NetStack::Default()->GetEthernetInterface()->IPAddress(); 43 panic("PXE boot: can't find remote disk on server %u.%u.%u.%u\n", 44 (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); 45 return B_ENTRY_NOT_FOUND; 46 } 47 48 devicesList->Add(remoteDisk); 49 return B_OK; 50 } 51 52 53 status_t 54 platform_get_boot_partition(struct stage2_args *args, Node *device, 55 NodeList *list, boot::Partition **_partition) 56 { 57 TRACE("platform_get_boot_partition\n"); 58 NodeIterator iterator = list->GetIterator(); 59 boot::Partition *partition = NULL; 60 while ((partition = (boot::Partition *)iterator.Next()) != NULL) { 61 // ToDo: just take the first partition for now 62 *_partition = partition; 63 return B_OK; 64 } 65 66 return B_ENTRY_NOT_FOUND; 67 } 68 69 70 status_t 71 platform_add_block_devices(stage2_args *args, NodeList *devicesList) 72 { 73 TRACE("platform_add_block_devices\n"); 74 return B_OK; 75 } 76 77 78 status_t 79 platform_register_boot_device(Node *device) 80 { 81 TRACE("platform_register_boot_device\n"); 82 83 gKernelArgs.platform_args.boot_drive_number = 0xffff; 84 gKernelArgs.platform_args.drives = NULL; 85 86 RemoteDisk *rd = static_cast<RemoteDisk *>(device); 87 UNDI *undi = static_cast<UNDI *>(NetStack::Default()->GetEthernetInterface()); 88 89 gKernelArgs.boot_disk.identifier.bus_type = UNKNOWN_BUS; 90 gKernelArgs.boot_disk.identifier.device_type = NETWORK_DEVICE; 91 gKernelArgs.boot_disk.identifier.device.network.client_ip = undi->IPAddress(); 92 gKernelArgs.boot_disk.identifier.device.network.server_ip = rd->ServerIPAddress(); 93 gKernelArgs.boot_disk.identifier.device.network.server_port = rd->ServerPort(); 94 gKernelArgs.boot_disk.partition_offset = 0; 95 gKernelArgs.boot_disk.user_selected = false; 96 gKernelArgs.boot_disk.booted_from_image = false; 97 gKernelArgs.boot_disk.booted_from_network = true; 98 gKernelArgs.boot_disk.cd = false; 99 100 return B_OK; 101 } 102