|
|
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.