|
|
1.1 ! root 1: \ ***************************************************************************** ! 2: \ * Copyright (c) 2004, 2008 IBM Corporation ! 3: \ * All rights reserved. ! 4: \ * This program and the accompanying materials ! 5: \ * are made available under the terms of the BSD License ! 6: \ * which accompanies this distribution, and is available at ! 7: \ * http://www.opensource.org/licenses/bsd-license.php ! 8: \ * ! 9: \ * Contributors: ! 10: \ * IBM Corporation - initial implementation ! 11: \ ****************************************************************************/ ! 12: ! 13: ! 14: \ Set debug-disk-label? to true to get debug messages for the disk-label code. ! 15: false VALUE debug-disk-label? ! 16: ! 17: \ This value defines the maximum number of blocks (512b) to load from a PREP ! 18: \ partition. This is required to keep the load time in reasonable limits if the ! 19: \ PREP partition becomes big. ! 20: \ If we ever want to put a large kernel with initramfs from a PREP partition ! 21: \ we might need to increase this value. The default value is 16384 blocks (8MB) ! 22: d# 16384 value max-prep-partition-blocks ! 23: ! 24: s" disk-label" device-name ! 25: ! 26: 0 INSTANCE VALUE partition ! 27: 0 INSTANCE VALUE part-offset ! 28: ! 29: 0 INSTANCE VALUE part-start ! 30: 0 INSTANCE VALUE lpart-start ! 31: 0 INSTANCE VALUE part-size ! 32: 0 INSTANCE VALUE dos-logical-partitions ! 33: ! 34: 0 INSTANCE VALUE block-size ! 35: 0 INSTANCE VALUE block ! 36: ! 37: 0 INSTANCE VALUE args ! 38: 0 INSTANCE VALUE args-len ! 39: ! 40: ! 41: INSTANCE VARIABLE block# \ variable to store logical sector# ! 42: INSTANCE VARIABLE hit# \ partition counter ! 43: INSTANCE VARIABLE success-flag ! 44: ! 45: \ ISO9660 specific information ! 46: 0ff constant END-OF-DESC ! 47: 3 constant PARTITION-ID ! 48: 48 constant VOL-PART-LOC ! 49: ! 50: ! 51: \ DOS partition label (MBR) specific structures ! 52: ! 53: STRUCT ! 54: 1b8 field mbr>boot-loader ! 55: /l field mbr>disk-signature ! 56: /w field mbr>null ! 57: 40 field mbr>partition-table ! 58: /w field mbr>magic ! 59: ! 60: CONSTANT /mbr ! 61: ! 62: STRUCT ! 63: /c field part-entry>active ! 64: /c field part-entry>start-head ! 65: /c field part-entry>start-sect ! 66: /c field part-entry>start-cyl ! 67: /c field part-entry>id ! 68: /c field part-entry>end-head ! 69: /c field part-entry>end-sect ! 70: /c field part-entry>end-cyl ! 71: /l field part-entry>sector-offset ! 72: /l field part-entry>sector-count ! 73: ! 74: CONSTANT /partition-entry ! 75: ! 76: ! 77: \ Defined by IEEE 1275-1994 (3.8.1) ! 78: ! 79: : offset ( d.rel -- d.abs ) ! 80: part-offset 0 d+ ! 81: ; ! 82: ! 83: : seek ( pos.lo pos.hi -- status ) ! 84: offset ! 85: debug-disk-label? IF 2dup ." seek-parent: pos.hi=0x" u. ." pos.lo=0x" u. THEN ! 86: s" seek" $call-parent ! 87: debug-disk-label? IF dup ." status=" . cr THEN ! 88: ; ! 89: ! 90: : read ( addr len -- actual ) ! 91: debug-disk-label? IF 2dup swap ." read-parent: addr=0x" u. ." len=" .d THEN ! 92: s" read" $call-parent ! 93: debug-disk-label? IF dup ." actual=" .d cr THEN ! 94: ; ! 95: ! 96: ! 97: \ read sector to array "block" ! 98: : read-sector ( sector-number -- ) ! 99: \ block-size is 0x200 on disks, 0x800 on cdrom drives ! 100: block-size * 0 seek drop \ seek to sector ! 101: block block-size read drop \ read sector ! 102: ; ! 103: ! 104: : (.part-entry) ( part-entry ) ! 105: cr ." part-entry>active: " dup part-entry>active c@ .d ! 106: cr ." part-entry>start-head: " dup part-entry>start-head c@ .d ! 107: cr ." part-entry>start-sect: " dup part-entry>start-sect c@ .d ! 108: cr ." part-entry>start-cyl: " dup part-entry>start-cyl c@ .d ! 109: cr ." part-entry>id: " dup part-entry>id c@ .d ! 110: cr ." part-entry>end-head: " dup part-entry>end-head c@ .d ! 111: cr ." part-entry>end-sect: " dup part-entry>end-sect c@ .d ! 112: cr ." part-entry>end-cyl: " dup part-entry>end-cyl c@ .d ! 113: cr ." part-entry>sector-offset: " dup part-entry>sector-offset l@-le .d ! 114: cr ." part-entry>sector-count: " dup part-entry>sector-count l@-le .d ! 115: cr ! 116: ; ! 117: ! 118: : (.name) r@ begin cell - dup @ <colon> = UNTIL xt>name cr type space ; ! 119: ! 120: : init-block ( -- ) ! 121: s" block-size" ['] $call-parent CATCH IF ABORT" parent has no block-size." THEN ! 122: to block-size ! 123: d# 2048 alloc-mem ! 124: dup d# 2048 erase ! 125: to block ! 126: debug-disk-label? IF ! 127: ." init-block: block-size=" block-size .d ." block=0x" block u. cr ! 128: THEN ! 129: ; ! 130: ! 131: ! 132: \ This word returns true if the currently loaded block has _NO_ MBR magic ! 133: : no-mbr? ( -- true|false ) ! 134: 0 read-sector block mbr>magic w@-le aa55 <> ! 135: ; ! 136: ! 137: : pc-extended-partition? ( part-entry-addr -- true|false ) ! 138: part-entry>id c@ ( id ) ! 139: dup 5 = swap ( true|false id ) ! 140: dup f = swap ( true|false true|false id ) ! 141: 85 = ( true|false true|false true|false ) ! 142: or or ( true|false ) ! 143: ; ! 144: ! 145: : partition>part-entry ( partition -- part-entry ) ! 146: 1- /partition-entry * block mbr>partition-table + ! 147: ; ! 148: ! 149: : partition>start-sector ( partition -- sector-offset ) ! 150: partition>part-entry part-entry>sector-offset l@-le ! 151: ; ! 152: ! 153: : count-dos-logical-partitions ( -- #logical-partitions ) ! 154: no-mbr? IF 0 EXIT THEN ! 155: 0 5 1 DO ( current ) ! 156: i partition>part-entry ( current part-entry ) ! 157: dup pc-extended-partition? IF ! 158: part-entry>sector-offset l@-le ( current sector ) ! 159: dup to part-start to lpart-start ( current ) ! 160: BEGIN ! 161: part-start read-sector \ read EBR ! 162: 1 partition>start-sector IF ! 163: \ ." Logical Partition found at " part-start .d cr ! 164: 1+ ! 165: THEN \ another logical partition ! 166: 2 partition>start-sector ! 167: ( current relative-sector ) ! 168: ?dup IF lpart-start + to part-start false ELSE true THEN ! 169: UNTIL ! 170: ELSE ! 171: drop ! 172: THEN ! 173: LOOP ! 174: ; ! 175: ! 176: : (get-dos-partition-params) ( ext-part-start part-entry -- offset count active? id ) ! 177: dup part-entry>sector-offset l@-le rot + swap ( offset part-entry ) ! 178: dup part-entry>sector-count l@-le swap ( offset count part-entry ) ! 179: dup part-entry>active c@ 80 = swap ( offset count active? part-entry ) ! 180: part-entry>id c@ ( offset count active? id ) ! 181: ; ! 182: ! 183: : find-dos-partition ( partition# -- false | offset count active? id true ) ! 184: to partition 0 to part-start 0 to part-offset ! 185: ! 186: \ no negative partitions ! 187: partition 0<= IF 0 to partition false EXIT THEN ! 188: ! 189: \ load MBR and check it ! 190: no-mbr? IF 0 to partition false EXIT THEN ! 191: ! 192: partition 4 <= IF \ Is this a primary partition? ! 193: 0 partition partition>part-entry ! 194: (get-dos-partition-params) ! 195: \ FIXME sanity checks? ! 196: true EXIT ! 197: ELSE ! 198: partition 4 - 0 5 1 DO ( logical-partition current ) ! 199: i partition>part-entry ( log-part current part-entry ) ! 200: dup pc-extended-partition? IF ! 201: part-entry>sector-offset l@-le ( log-part current sector ) ! 202: dup to part-start to lpart-start ( log-part current ) ! 203: BEGIN ! 204: part-start read-sector \ read EBR ! 205: 1 partition>start-sector IF \ first partition entry ! 206: 1+ 2dup = IF ( log-part current ) ! 207: 2drop ! 208: part-start 1 partition>part-entry ! 209: (get-dos-partition-params) ! 210: true UNLOOP EXIT ! 211: THEN ! 212: 2 partition>start-sector ! 213: ( log-part current relative-sector ) ! 214: ! 215: ?dup IF lpart-start + to part-start false ELSE true THEN ! 216: ELSE ! 217: true ! 218: THEN ! 219: UNTIL ! 220: ELSE ! 221: drop ! 222: THEN ! 223: LOOP ! 224: 2drop false ! 225: THEN ! 226: ; ! 227: ! 228: : try-dos-partition ( -- okay? ) ! 229: \ Read partition table and check magic. ! 230: no-mbr? IF cr ." No DOS disk-label found." cr false EXIT THEN ! 231: ! 232: count-dos-logical-partitions TO dos-logical-partitions ! 233: ! 234: debug-disk-label? IF ! 235: ." Found " dos-logical-partitions .d ." logical partitions" cr ! 236: ." Partition = " partition .d cr ! 237: THEN ! 238: ! 239: partition 1 5 dos-logical-partitions + ! 240: within 0= IF ! 241: cr ." Partition # not 1-" 4 dos-logical-partitions + . cr false EXIT ! 242: THEN ! 243: ! 244: \ Could/should check for valid partition here... the magic is not enough really. ! 245: ! 246: \ Get the partition offset. ! 247: ! 248: partition find-dos-partition IF ! 249: ( offset count active? id ) ! 250: 2drop drop ! 251: block-size * to part-offset ! 252: true ! 253: ELSE ! 254: false ! 255: THEN ! 256: ; ! 257: ! 258: \ Check for an ISO-9660 filesystem on the disk ! 259: \ : try-iso9660-partition ( -- true|false ) ! 260: \ implement me if you can ;-) ! 261: \ ; ! 262: ! 263: ! 264: \ Check for an ISO-9660 filesystem on the disk ! 265: \ (cf. CHRP IEEE 1275 spec., chapter 11.1.2.3) ! 266: : has-iso9660-filesystem ( -- TRUE|FALSE ) ! 267: \ Seek to the begining of logical 2048-byte sector 16 ! 268: \ refer to Chapter C.11.1 in PAPR 2.0 Spec ! 269: \ was: 10 read-sector, but this might cause trouble if you ! 270: \ try booting an ISO image from a device with 512b sectors. ! 271: 10 800 * 0 seek drop \ seek to sector ! 272: block 800 read drop \ read sector ! 273: \ Check for CD-ROM volume magic: ! 274: block c@ 1 = ! 275: block 1+ 5 s" CD001" str= ! 276: and ! 277: dup IF 800 to block-size THEN ! 278: ; ! 279: ! 280: ! 281: \ Load from first active DOS boot partition. ! 282: ! 283: \ NOTE: block-size is always 512 bytes for DOS partition tables. ! 284: ! 285: : load-from-dos-boot-partition ( addr -- size ) ! 286: no-mbr? IF FALSE EXIT THEN \ read MBR and check for DOS disk-label magic ! 287: ! 288: count-dos-logical-partitions TO dos-logical-partitions ! 289: ! 290: debug-disk-label? IF ! 291: ." Found " dos-logical-partitions .d ." logical partitions" cr ! 292: ." Partition = " partition .d cr ! 293: THEN ! 294: ! 295: \ Now walk through the partitions: ! 296: 5 dos-logical-partitions + 1 DO ! 297: \ ." checking partition " i . ! 298: i find-dos-partition IF ( addr offset count active? id ) ! 299: 41 = and ( addr offset count prep-boot-part? ) ! 300: IF ( addr offset count ) ! 301: max-prep-partition-blocks min \ reduce load size ! 302: swap ( addr count offset ) ! 303: block-size * to part-offset ! 304: 0 0 seek drop ( addr offset ) ! 305: block-size * read ( size ) ! 306: UNLOOP EXIT ! 307: ELSE ! 308: 2drop ( addr ) ! 309: THEN ! 310: THEN ! 311: LOOP ! 312: drop 0 ! 313: ; ! 314: ! 315: ! 316: \ load from a bootable partition ! 317: ! 318: : load-from-boot-partition ( addr -- size ) ! 319: load-from-dos-boot-partition ! 320: \ More boot partition formats ... ! 321: ; ! 322: ! 323: ! 324: ! 325: \ Extract the boot loader path from a bootinfo.txt file ! 326: \ In: address and length of buffer where the bootinfo.txt has been loaded to. ! 327: \ Out: string address and length of the boot loader (within the input buffer) ! 328: \ or a string with length = 0 when parsing failed. ! 329: ! 330: \ Here is a sample bootinfo file: ! 331: \ <chrp-boot> ! 332: \ <description>Linux Distribution</description> ! 333: \ <os-name>Linux</os-name> ! 334: \ <boot-script>boot &device;:1,\boot\yaboot.ibm</boot-script> ! 335: \ <icon size=64,64 color-space=3,3,2> ! 336: \ <bitmap>[..]</bitmap> ! 337: \ </icon> ! 338: \ </chrp-boot> ! 339: ! 340: : parse-bootinfo-txt ( addr len -- str len ) ! 341: 2dup s" <boot-script>" find-substr ( addr len pos1 ) ! 342: 2dup = IF ! 343: \ String not found ! 344: 3drop 0 0 EXIT ! 345: THEN ! 346: dup >r - swap r> + swap ( addr1 len1 ) ! 347: 2dup [char] \ findchar drop ( addr1 len1 pos2 ) ! 348: dup >r - swap r> + swap ( addr2 len2 ) ! 349: 2dup s" </boot-script>" find-substr nip ( addr2 len3 ) ! 350: ; ! 351: ! 352: \ Try to load \ppc\bootinfo.txt from the disk (used mainly on CD-ROMs), and if ! 353: \ available, get the boot loader path from this file and load it. ! 354: \ See the "CHRP system binding to IEEE 1275" specification for more information ! 355: \ about bootinfo.txt. An example file can be found in the comment of ! 356: \ parse-bootinfo-txt ( addr len -- str len ) ! 357: ! 358: : load-chrp-boot-file ( addr -- size ) ! 359: \ Create bootinfo.txt path name and load that file: ! 360: my-self parent ihandle>phandle node>path ! 361: s" :\ppc\bootinfo.txt" $cat strdup ( addr str len ) ! 362: open-dev dup 0= IF 2drop 0 EXIT THEN ! 363: >r dup ( addr addr R:ihandle ) ! 364: dup s" load" r@ $call-method ( addr addr size R:ihandle ) ! 365: r> close-dev ( addr addr size ) ! 366: ! 367: \ Now parse the information from bootinfo.txt: ! 368: parse-bootinfo-txt ( addr fnstr fnlen ) ! 369: dup 0= IF 3drop 0 EXIT THEN ! 370: \ Create the full path to the boot loader: ! 371: my-self parent ihandle>phandle node>path ( addr fnstr fnlen nstr nlen ) ! 372: s" :" $cat 2swap $cat strdup ( addr str len ) ! 373: \ Update the bootpath: ! 374: 2dup encode-string s" bootpath" set-chosen ! 375: \ And finally load the boot loader itself: ! 376: open-dev dup 0= IF ." failed to load CHRP boot loader." 2drop 0 EXIT THEN ! 377: >r s" load" r@ $call-method ( size R:ihandle ) ! 378: r> close-dev ( size ) ! 379: ; ! 380: ! 381: \ parse partition number from my-args ! 382: ! 383: \ my-args has the following format ! 384: \ [<partition>[,<path>]] ! 385: ! 386: \ | example my-args | example boot command | ! 387: \ +------------------+---------------------------+ ! 388: \ | 1,\boot\vmlinuz | boot disk:1,\boot\vmlinuz | ! 389: \ | 2 | boot disk:2 | ! 390: ! 391: \ 0 means the whole disk, this is the same behavior ! 392: \ as if no partition is specified (yaboot wants this). ! 393: ! 394: : parse-partition ( -- okay? ) ! 395: 0 to partition ! 396: 0 to part-offset ! 397: ! 398: my-args to args-len to args ! 399: ! 400: \ Fix up the "0" thing yaboot does. ! 401: args-len 1 = IF args c@ [char] 0 = IF 0 to args-len THEN THEN ! 402: ! 403: \ Check for "full disk" arguments. ! 404: my-args [char] , findchar 0= IF true EXIT THEN drop \ no comma ! 405: my-args [char] , split to args-len to args ! 406: dup 0= IF 2drop true EXIT THEN \ no first argument ! 407: ! 408: \ Check partition #. ! 409: base @ >r decimal $number r> base ! ! 410: IF cr ." Not a partition #" false EXIT THEN ! 411: ! 412: \ Store part #, done. ! 413: to partition ! 414: true ! 415: ; ! 416: ! 417: ! 418: \ try-files and try-partitions ! 419: ! 420: : (interpose-filesystem) ( str len -- ) ! 421: find-package IF args args-len rot interpose THEN ! 422: ; ! 423: ! 424: : try-dos-files ( -- found? ) ! 425: no-mbr? IF false EXIT THEN ! 426: ! 427: \ block 0 byte 0-2 is a jump instruction in all FAT ! 428: \ filesystems. ! 429: \ e9 and eb are jump instructions in x86 assembler. ! 430: block c@ e9 <> IF ! 431: block c@ eb <> ! 432: block 2+ c@ 90 <> or ! 433: IF false EXIT THEN ! 434: THEN ! 435: s" fat-files" (interpose-filesystem) ! 436: true ! 437: ; ! 438: ! 439: : try-ext2-files ( -- found? ) ! 440: 2 read-sector \ read first superblock ! 441: block d# 56 + w@-le \ fetch s_magic ! 442: ef53 <> IF false EXIT THEN \ s_magic found? ! 443: s" ext2-files" (interpose-filesystem) ! 444: true ! 445: ; ! 446: ! 447: ! 448: : try-iso9660-files ! 449: has-iso9660-filesystem 0= IF false exit THEN ! 450: s" iso-9660" (interpose-filesystem) ! 451: true ! 452: ; ! 453: ! 454: : try-files ( -- found? ) ! 455: \ If no path, then full disk. ! 456: args-len 0= IF true EXIT THEN ! 457: ! 458: try-dos-files IF true EXIT THEN ! 459: try-ext2-files IF true EXIT THEN ! 460: try-iso9660-files IF true EXIT THEN ! 461: ! 462: \ ... more filesystem types here ... ! 463: ! 464: false ! 465: ; ! 466: ! 467: : try-partitions ( -- found? ) ! 468: try-dos-partition IF try-files EXIT THEN ! 469: \ try-iso9660-partition IF try-files EXIT THEN ! 470: \ ... more partition types here... ! 471: false ! 472: ; ! 473: ! 474: \ Interface functions for disk-label package ! 475: \ as defined by IEEE 1275-1994 3.8.1 ! 476: ! 477: : close ( -- ) ! 478: debug-disk-label? IF ." Closing disk-label: block=0x" block u. ." block-size=" block-size .d cr THEN ! 479: block d# 2048 free-mem ! 480: ; ! 481: ! 482: ! 483: : open ( -- true|false ) ! 484: init-block ! 485: ! 486: parse-partition 0= IF ! 487: close ! 488: false EXIT ! 489: THEN ! 490: ! 491: partition IF ! 492: try-partitions ! 493: ELSE ! 494: try-files ! 495: THEN ! 496: dup 0= IF debug-disk-label? IF ." not found." cr THEN close THEN \ free memory again ! 497: ; ! 498: ! 499: ! 500: \ Boot & Load w/o arguments is assumed to be boot from boot partition ! 501: ! 502: : load ( addr -- size ) ! 503: debug-disk-label? IF ! 504: ." load: " dup u. cr ! 505: THEN ! 506: ! 507: args-len IF ! 508: TRUE ABORT" Load done w/o filesystem" ! 509: ELSE ! 510: partition IF ! 511: 0 0 seek drop ! 512: 200000 read ! 513: ELSE ! 514: has-iso9660-filesystem IF ! 515: dup load-chrp-boot-file ?dup 0 > IF nip EXIT THEN ! 516: THEN ! 517: load-from-boot-partition ! 518: dup 0= ABORT" No boot partition found" ! 519: THEN ! 520: THEN ! 521: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.