|
|
1.1 ! root 1: /* ! 2: * Creation Date: <2003/12/03 22:10:45 samuel> ! 3: * Time-stamp: <2004/01/07 19:17:45 samuel> ! 4: * ! 5: * <disk-label.c> ! 6: * ! 7: * Partition support ! 8: * ! 9: * Copyright (C) 2003, 2004 Samuel Rydh ([email protected]) ! 10: * ! 11: * This program is free software; you can redistribute it and/or ! 12: * modify it under the terms of the GNU General Public License ! 13: * version 2 ! 14: * ! 15: */ ! 16: ! 17: #include "config.h" ! 18: #include "libopenbios/bindings.h" ! 19: #include "libopenbios/load.h" ! 20: #include "libc/diskio.h" ! 21: #include "libc/vsprintf.h" ! 22: #include "packages.h" ! 23: ! 24: //#define DEBUG_DISK_LABEL ! 25: ! 26: #ifdef DEBUG_DISK_LABEL ! 27: #define DPRINTF(fmt, args...) \ ! 28: do { printk("DISK-LABEL - %s: " fmt, __func__ , ##args); } while (0) ! 29: #else ! 30: #define DPRINTF(fmt, args...) do { } while (0) ! 31: #endif ! 32: ! 33: typedef struct { ! 34: xt_t parent_seek_xt; ! 35: xt_t parent_tell_xt; ! 36: xt_t parent_read_xt; ! 37: ! 38: ucell offs_hi, offs_lo; ! 39: ucell size_hi, size_lo; ! 40: int block_size; ! 41: int type; /* partition type or -1 */ ! 42: ! 43: ihandle_t part_ih; ! 44: phandle_t filesystem_ph; ! 45: } dlabel_info_t; ! 46: ! 47: DECLARE_NODE( dlabel, 0, sizeof(dlabel_info_t), "/packages/disk-label" ); ! 48: ! 49: ! 50: /* ( -- ) */ ! 51: static void ! 52: dlabel_close( __attribute__((unused))dlabel_info_t *di ) ! 53: { ! 54: } ! 55: ! 56: /* ( -- success? ) */ ! 57: static void ! 58: dlabel_open( dlabel_info_t *di ) ! 59: { ! 60: char *path; ! 61: char block0[512]; ! 62: phandle_t ph; ! 63: int success=0; ! 64: cell status; ! 65: ! 66: path = my_args_copy(); ! 67: ! 68: DPRINTF("dlabel-open '%s'\n", path ); ! 69: ! 70: di->part_ih = 0; ! 71: ! 72: /* Find parent methods */ ! 73: di->filesystem_ph = 0; ! 74: di->parent_seek_xt = find_parent_method("seek"); ! 75: di->parent_tell_xt = find_parent_method("tell"); ! 76: di->parent_read_xt = find_parent_method("read"); ! 77: ! 78: /* Read first block from parent device */ ! 79: DPUSH(0); ! 80: call_package(di->parent_seek_xt, my_parent()); ! 81: POP(); ! 82: ! 83: PUSH(pointer2cell(block0)); ! 84: PUSH(sizeof(block0)); ! 85: call_package(di->parent_read_xt, my_parent()); ! 86: status = POP(); ! 87: if (status != sizeof(block0)) ! 88: goto out; ! 89: ! 90: /* Find partition handler */ ! 91: PUSH( pointer2cell(block0) ); ! 92: selfword("find-part-handler"); ! 93: ph = POP_ph(); ! 94: if( ph ) { ! 95: /* We found a suitable partition handler, so interpose it */ ! 96: DPRINTF("Partition found on disk - scheduling interpose with ph " FMT_ucellx "\n", ph); ! 97: ! 98: push_str(path); ! 99: PUSH_ph(ph); ! 100: fword("interpose"); ! 101: ! 102: success = 1; ! 103: } else { ! 104: /* unknown (or missing) partition map, ! 105: * try the whole disk ! 106: */ ! 107: ! 108: DPRINTF("Unknown or missing partition map; trying whole disk\n"); ! 109: ! 110: /* Probe for filesystem from start of device */ ! 111: DPUSH ( 0 ); ! 112: PUSH_ih( my_self() ); ! 113: selfword("find-filesystem"); ! 114: ph = POP_ph(); ! 115: if( ph ) { ! 116: /* If we have been asked to open a particular file, interpose the filesystem package with the passed filename as an argument */ ! 117: di->filesystem_ph = ph; ! 118: ! 119: DPRINTF("Located filesystem with ph " FMT_ucellx "\n", ph); ! 120: DPRINTF("path: %s length: %d\n", path, strlen(path)); ! 121: ! 122: if (path && strlen(path)) { ! 123: DPRINTF("INTERPOSE!\n"); ! 124: ! 125: push_str( path ); ! 126: PUSH_ph( ph ); ! 127: fword("interpose"); ! 128: } ! 129: } else if (path && strcmp(path, "%BOOT") != 0) { ! 130: goto out; ! 131: } ! 132: ! 133: success = 1; ! 134: } ! 135: ! 136: out: ! 137: if( path ) ! 138: free( path ); ! 139: if( !success ) { ! 140: dlabel_close( di ); ! 141: RET(0); ! 142: } ! 143: PUSH(-1); ! 144: } ! 145: ! 146: /* ( addr len -- actual ) */ ! 147: static void ! 148: dlabel_read( dlabel_info_t *di ) ! 149: { ! 150: /* Call back up to parent */ ! 151: call_package(di->parent_read_xt, my_parent()); ! 152: } ! 153: ! 154: /* ( pos.d -- status ) */ ! 155: static void ! 156: dlabel_seek( dlabel_info_t *di ) ! 157: { ! 158: /* Call back up to parent */ ! 159: call_package(di->parent_seek_xt, my_parent()); ! 160: } ! 161: ! 162: /* ( -- filepos.d ) */ ! 163: static void ! 164: dlabel_tell( dlabel_info_t *di ) ! 165: { ! 166: /* Call back up to parent */ ! 167: call_package(di->parent_tell_xt, my_parent()); ! 168: } ! 169: ! 170: /* ( addr len -- actual ) */ ! 171: static void ! 172: dlabel_write( __attribute__((unused)) dlabel_info_t *di ) ! 173: { ! 174: DDROP(); ! 175: PUSH( -1 ); ! 176: } ! 177: ! 178: /* ( addr -- size ) */ ! 179: static void ! 180: dlabel_load( __attribute__((unused)) dlabel_info_t *di ) ! 181: { ! 182: /* Try the load method of the part package */ ! 183: #ifdef DEBUG_DISK_LABEL ! 184: char *buf; ! 185: #endif ! 186: xt_t xt; ! 187: ! 188: #ifdef DEBUG_DISK_LABEL ! 189: buf = (char *)POP(); ! 190: #else ! 191: POP(); ! 192: #endif ! 193: ! 194: DPRINTF("load invoked with address %p\n", buf); ! 195: ! 196: /* If we have a partition handle, invoke the load word on it */ ! 197: if (di->part_ih) { ! 198: xt = find_ih_method("load", di->part_ih); ! 199: if (!xt) { ! 200: forth_printf("load currently not implemented for ihandle " FMT_ucellx "\n", di->part_ih); ! 201: PUSH(0); ! 202: return; ! 203: } ! 204: ! 205: DPRINTF("calling load on ihandle " FMT_ucellx "\n", di->part_ih); ! 206: ! 207: call_package(xt, di->part_ih); ! 208: } else { ! 209: /* Otherwise attempt load directly on the raw disk */ ! 210: DPRINTF("calling load on raw disk ihandle " FMT_ucellx "\n", my_self()); ! 211: ! 212: load(my_self()); ! 213: } ! 214: } ! 215: ! 216: /* ( pathstr len -- ) */ ! 217: static void ! 218: dlabel_dir( dlabel_info_t *di ) ! 219: { ! 220: if ( di->filesystem_ph ) { ! 221: PUSH( my_self() ); ! 222: push_str("dir"); ! 223: PUSH( di->filesystem_ph ); ! 224: fword("find-method"); ! 225: POP(); ! 226: fword("execute"); ! 227: } else { ! 228: forth_printf("disk-label: Unable to determine filesystem\n"); ! 229: POP(); ! 230: POP(); ! 231: } ! 232: } ! 233: ! 234: NODE_METHODS( dlabel ) = { ! 235: { "open", dlabel_open }, ! 236: { "close", dlabel_close }, ! 237: { "load", dlabel_load }, ! 238: { "read", dlabel_read }, ! 239: { "write", dlabel_write }, ! 240: { "seek", dlabel_seek }, ! 241: { "tell", dlabel_tell }, ! 242: { "dir", dlabel_dir }, ! 243: }; ! 244: ! 245: void ! 246: disklabel_init( void ) ! 247: { ! 248: REGISTER_NODE( dlabel ); ! 249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.