1 /* 2 * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include "Handle.h" 7 #include "machine.h" 8 9 #include <boot/platform.h> 10 #include <boot/vfs.h> 11 #include <boot/stdio.h> 12 #include <boot/stage2.h> 13 #include <boot/net/NetStack.h> 14 #include <boot/net/RemoteDisk.h> 15 #include <platform/openfirmware/devices.h> 16 #include <platform/openfirmware/openfirmware.h> 17 #include <util/kernel_cpp.h> 18 19 #include <string.h> 20 21 22 char sBootPath[192]; 23 24 25 status_t 26 platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) 27 { 28 // print out the boot path (to be removed later?) 29 30 int length = of_getprop(gChosen, "bootpath", sBootPath, sizeof(sBootPath)); 31 if (length <= 1) 32 return B_ENTRY_NOT_FOUND; 33 printf("boot path = \"%s\"\n", sBootPath); 34 35 int node = of_finddevice(sBootPath); 36 if (node != OF_FAILED) { 37 char type[16]; 38 of_getprop(node, "device_type", type, sizeof(type)); 39 printf("boot type = %s\n", type); 40 41 // If the boot device is a network device, we try to find a 42 // "remote disk" at this point. 43 if (strcmp(type, "network") == 0) { 44 // init the net stack 45 status_t error = net_stack_init(); 46 if (error != B_OK) 47 return error; 48 49 // init a remote disk, if possible 50 RemoteDisk *remoteDisk = RemoteDisk::FindAnyRemoteDisk(); 51 if (!remoteDisk) 52 return B_ENTRY_NOT_FOUND; 53 54 devicesList->Add(remoteDisk); 55 return B_OK; 56 } 57 58 if (strcmp("block", type) != 0) { 59 printf("boot device is not a block device!\n"); 60 return B_ENTRY_NOT_FOUND; 61 } 62 } else 63 printf("could not open boot path.\n"); 64 65 /* char name[256]; 66 strcpy(name, sBootPath); 67 strcat(name, ":kernel_ppc"); 68 int kernel = of_open(name); 69 if (kernel == OF_FAILED) { 70 puts("open kernel failed"); 71 } else 72 puts("open kernel succeeded"); 73 */ 74 int handle = of_open(sBootPath); 75 if (handle == OF_FAILED) { 76 puts("\t\t(open failed)"); 77 return B_ERROR; 78 } 79 80 Handle *device = new(nothrow) Handle(handle); 81 if (device == NULL) 82 return B_NO_MEMORY; 83 84 devicesList->Add(device); 85 return B_OK; 86 } 87 88 89 status_t 90 platform_get_boot_partition(struct stage2_args *args, Node *device, 91 NodeList *list, boot::Partition **_partition) 92 { 93 NodeIterator iterator = list->GetIterator(); 94 boot::Partition *partition = NULL; 95 while ((partition = (boot::Partition *)iterator.Next()) != NULL) { 96 // ToDo: just take the first partition for now 97 *_partition = partition; 98 return B_OK; 99 } 100 101 return B_ENTRY_NOT_FOUND; 102 } 103 104 105 #define DUMPED_BLOCK_SIZE 16 106 107 void 108 dumpBlock(const char *buffer, int size, const char *prefix) 109 { 110 int i; 111 112 for (i = 0; i < size;) { 113 int start = i; 114 115 printf(prefix); 116 for (; i < start+DUMPED_BLOCK_SIZE; i++) { 117 if (!(i % 4)) 118 printf(" "); 119 120 if (i >= size) 121 printf(" "); 122 else 123 printf("%02x", *(unsigned char *)(buffer + i)); 124 } 125 printf(" "); 126 127 for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) { 128 if (i < size) { 129 char c = buffer[i]; 130 131 if (c < 30) 132 printf("."); 133 else 134 printf("%c", c); 135 } else 136 break; 137 } 138 printf("\n"); 139 } 140 } 141 142 143 status_t 144 platform_add_block_devices(stage2_args *args, NodeList *devicesList) 145 { 146 // add all block devices to the list of possible boot devices 147 148 int cookie = 0; 149 char path[256]; 150 status_t status; 151 while ((status = of_get_next_device(&cookie, 0, "block", path, 152 sizeof(path))) == B_OK) { 153 if (!strcmp(path, sBootPath)) { 154 // don't add the boot device twice 155 continue; 156 } 157 158 // Adjust the arguments passed to the open command so that 159 // the disk-label package is by-passed - unfortunately, 160 // this is implementation specific (and I found no docs 161 // for the Apple OF disk-label usage, of course) 162 163 // SUN's OpenBoot: 164 //strcpy(path + strlen(path), ":nolabel"); 165 // Apple: 166 if (gMachine & MACHINE_MAC) 167 strcpy(path + strlen(path), ":0"); 168 169 printf("\t%s\n", path); 170 171 int handle = of_open(path); 172 if (handle == OF_FAILED) { 173 puts("\t\t(failed)"); 174 continue; 175 } 176 177 Handle *device = new(nothrow) Handle(handle); 178 printf("\t\t(could open device, handle = %p, node = %p)\n", (void *)handle, device); 179 180 devicesList->Add(device); 181 } 182 printf("\t(loop ended with %ld)\n", status); 183 184 return B_OK; 185 } 186 187 status_t 188 platform_register_boot_device(Node *device) 189 { 190 disk_identifier disk; 191 192 disk.bus_type = UNKNOWN_BUS; 193 disk.device_type = UNKNOWN_DEVICE; 194 disk.device.unknown.size = device->Size(); 195 196 gKernelArgs.boot_volume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, 197 &disk, sizeof(disk_identifier)); 198 199 return B_OK; 200 } 201 202