1\ $NetBSD: bootblk.fth,v 1.8 2008/06/29 14:13:23 jdc Exp $ 2\ 3\ IEEE 1275 Open Firmware Boot Block 4\ 5\ Parses disklabel and UFS and loads the file called `ofwboot' 6\ 7\ 8\ Copyright (c) 1998 Eduardo Horvath. 9\ All rights reserved. 10\ 11\ Redistribution and use in source and binary forms, with or without 12\ modification, are permitted provided that the following conditions 13\ are met: 14\ 1. Redistributions of source code must retain the above copyright 15\ notice, this list of conditions and the following disclaimer. 16\ 2. Redistributions in binary form must reproduce the above copyright 17\ notice, this list of conditions and the following disclaimer in the 18\ documentation and/or other materials provided with the distribution. 19\ 3. All advertising materials mentioning features or use of this software 20\ must display the following acknowledgement: 21\ This product includes software developed by Eduardo Horvath. 22\ 4. The name of the author may not be used to endorse or promote products 23\ derived from this software without specific prior written permission 24\ 25\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26\ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27\ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28\ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29\ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30\ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31\ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32\ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33\ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34\ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35\ 36 37offset16 38hex 39headers 40 41false value boot-debug? 42 43\ 44\ First some housekeeping: Open /chosen and set up vectors into 45\ client-services 46 47" /chosen" find-package 0= if ." Cannot find /chosen" 0 then 48constant chosen-phandle 49 50" /openprom/client-services" find-package 0= if 51 ." Cannot find client-services" cr abort 52then constant cif-phandle 53 54defer cif-claim ( align size virt -- base ) 55defer cif-release ( size virt -- ) 56defer cif-open ( cstr -- ihandle|0 ) 57defer cif-close ( ihandle -- ) 58defer cif-read ( len adr ihandle -- #read ) 59defer cif-seek ( low high ihandle -- -1|0|1 ) 60\ defer cif-peer ( phandle -- phandle ) 61\ defer cif-getprop ( len adr cstr phandle -- ) 62 63: find-cif-method ( method,len -- xf ) 64 cif-phandle find-method drop 65; 66 67" claim" find-cif-method to cif-claim 68" open" find-cif-method to cif-open 69" close" find-cif-method to cif-close 70" read" find-cif-method to cif-read 71" seek" find-cif-method to cif-seek 72 73: twiddle ( -- ) ." ." ; \ Need to do this right. Just spit out periods for now. 74 75\ 76\ Support routines 77\ 78 79: strcmp ( s1 l1 s2 l2 -- true:false ) 80 rot tuck <> if 3drop false exit then 81 comp 0= 82; 83 84\ Move string into buffer 85 86: strmov ( s1 l1 d -- d l1 ) 87 dup 2over swap -rot ( s1 l1 d s1 d l1 ) 88 move ( s1 l1 d ) 89 rot drop swap 90; 91 92\ Move s1 on the end of s2 and return the result 93 94: strcat ( s1 l1 s2 l2 -- d tot ) 95 2over swap ( s1 l1 s2 l2 l1 s1 ) 96 2over + rot ( s1 l1 s2 l2 s1 d l1 ) 97 move rot + ( s1 s2 len ) 98 rot drop ( s2 len ) 99; 100 101: strchr ( s1 l1 c -- s2 l2 ) 102 begin 103 dup 2over 0= if ( s1 l1 c c s1 ) 104 2drop drop exit then 105 c@ = if ( s1 l1 c ) 106 drop exit then 107 -rot /c - swap ca1+ ( c l2 s2 ) 108 swap rot 109 again 110; 111 112 113: cstr ( ptr -- str len ) 114 dup 115 begin dup c@ 0<> while + repeat 116 over - 117; 118 119\ 120\ BSD FFS parameters 121\ 122 123fload assym.fth.h 124 125sbsize buffer: sb-buf 126-1 value boot-ihandle 127dev_bsize value bsize 1280 value raid-offset \ Offset if it's a raid-frame partition 129false value force-raid \ Force reads from raid offset 130 131: strategy ( addr size start -- nread ) 132 raid-offset + bsize * 0 " seek" boot-ihandle $call-method 133 -1 = if 134 ." strategy: Seek failed" cr 135 abort 136 then 137 " read" boot-ihandle $call-method 138; 139 140\ 141\ Cylinder group macros 142\ 143 144: cgbase ( cg fs -- cgbase ) fs_fpg l@ * ; 145: cgstart ( cg fs -- cgstart ) 146 2dup fs_old_cgmask l@ not and ( cg fs stuff -- ) 147 over fs_old_cgoffset l@ * -rot ( stuffcg fs -- ) 148 cgbase + 149; 150: cgdmin ( cg fs -- 1st-data-block ) dup fs_dblkno l@ -rot cgstart + ; 151: cgimin ( cg fs -- inode-block ) dup fs_iblkno l@ -rot cgstart + ; 152: cgsblock ( cg fs -- super-block ) dup fs_sblkno l@ -rot cgstart + ; 153: cgstod ( cg fs -- cg-block ) dup fs_cblkno l@ -rot cgstart + ; 154 155\ 156\ Block and frag position macros 157\ 158 159: blkoff ( pos fs -- off ) fs_qbmask x@ and ; 160: fragoff ( pos fs -- off ) fs_qfmask x@ and ; 161: lblktosize ( blk fs -- off ) fs_bshift l@ << ; 162: lblkno ( pos fs -- off ) fs_bshift l@ >> ; 163: numfrags ( pos fs -- off ) fs_fshift l@ >> ; 164: blkroundup ( pos fs -- off ) dup fs_bmask l@ -rot fs_qbmask x@ + and ; 165: fragroundup ( pos fs -- off ) dup fs_fmask l@ -rot fs_qfmask x@ + and ; 166\ : fragroundup ( pos fs -- off ) tuck fs_qfmask x@ + swap fs_fmask l@ and ; 167: fragstoblks ( pos fs -- off ) fs_fragshift l@ >> ; 168: blkstofrags ( blk fs -- frag ) fs_fragshift l@ << ; 169: fragnum ( fsb fs -- off ) fs_frag l@ 1- and ; 170: blknum ( fsb fs -- off ) fs_frag l@ 1- not and ; 171: dblksize ( lbn dino fs -- size ) 172 -rot ( fs lbn dino ) 173 di_size x@ ( fs lbn di_size ) 174 -rot dup 1+ ( di_size fs lbn lbn+1 ) 175 2over fs_bshift l@ ( di_size fs lbn lbn+1 di_size b_shift ) 176 rot swap << >= ( di_size fs lbn res1 ) 177 swap ndaddr >= or if ( di_size fs ) 178 swap drop fs_bsize l@ exit ( size ) 179 then tuck blkoff swap fragroundup ( size ) 180; 181 182 183: ino-to-cg ( ino fs -- cg ) fs_ipg l@ / ; 184: ino-to-fsbo ( ino fs -- fsb0 ) fs_inopb l@ mod ; 185: ino-to-fsba ( ino fs -- ba ) \ Need to remove the stupid stack diags someday 186 2dup ( ino fs ino fs ) 187 ino-to-cg ( ino fs cg ) 188 over ( ino fs cg fs ) 189 cgimin ( ino fs inode-blk ) 190 -rot ( inode-blk ino fs ) 191 tuck ( inode-blk fs ino fs ) 192 fs_ipg l@ ( inode-blk fs ino ipg ) 193 mod ( inode-blk fs mod ) 194 swap ( inode-blk mod fs ) 195 dup ( inode-blk mod fs fs ) 196 fs_inopb l@ ( inode-blk mod fs inopb ) 197 rot ( inode-blk fs inopb mod ) 198 swap ( inode-blk fs mod inopb ) 199 / ( inode-blk fs div ) 200 swap ( inode-blk div fs ) 201 blkstofrags ( inode-blk frag ) 202 + 203; 204: fsbtodb ( fsb fs -- db ) fs_fsbtodb l@ << ; 205 206\ 207\ File stuff 208\ 209 210niaddr /w* constant narraysize 211 212struct 213 8 field >f_ihandle \ device handle 214 8 field >f_seekp \ seek pointer 215 8 field >f_fs \ pointer to super block 216 ufs1_dinode_SIZEOF field >f_di \ copy of on-disk inode 217 8 field >f_buf \ buffer for data block 218 4 field >f_buf_size \ size of data block 219 4 field >f_buf_blkno \ block number of data block 220constant file_SIZEOF 221 222file_SIZEOF buffer: the-file 223sb-buf the-file >f_fs x! 224 225ufs1_dinode_SIZEOF buffer: cur-inode 226h# 2000 buffer: indir-block 227-1 value indir-addr 228 229\ 230\ Translate a fileblock to a disk block 231\ 232\ We only allow single indirection 233\ 234 235: block-map ( fileblock -- diskblock ) 236 \ Direct block? 237 dup ndaddr < if ( fileblock ) 238 cur-inode di_db ( arr-indx arr-start ) 239 swap la+ l@ exit ( diskblock ) 240 then ( fileblock ) 241 ndaddr - ( fileblock' ) 242 \ Now we need to check the indirect block 243 dup sb-buf fs_nindir l@ < if ( fileblock' ) 244 cur-inode di_ib l@ dup ( fileblock' indir-block indir-block ) 245 indir-addr <> if ( fileblock' indir-block ) 246 to indir-addr ( fileblock' ) 247 indir-block ( fileblock' indir-block ) 248 sb-buf dup fs_bsize l@ ( fileblock' indir-block fs fs_bsize ) 249 swap indir-addr swap ( fileblock' indir-block fs_bsize indiraddr fs ) 250 fsbtodb ( fileblock' indir-block fs_bsize db ) 251 strategy ( fileblock' nread ) 252 then ( fileblock' nread|indir-block ) 253 drop \ Really should check return value 254 indir-block swap la+ l@ exit 255 then 256 dup sb-buf fs_nindir - ( fileblock'' ) 257 \ Now try 2nd level indirect block -- just read twice 258 dup sb-buf fs_nindir l@ dup * < if ( fileblock'' ) 259 cur-inode di_ib 1 la+ l@ ( fileblock'' indir2-block ) 260 to indir-addr ( fileblock'' ) 261 \ load 1st level indir block 262 indir-block ( fileblock'' indir-block ) 263 sb-buf dup fs_bsize l@ ( fileblock'' indir-block fs fs_bsize ) 264 swap indir-addr swap ( fileblock'' indir-block fs_bsize indiraddr fs ) 265 fsbtodb ( fileblock'' indir-block fs_bsize db ) 266 strategy ( fileblock'' nread ) 267 drop ( fileblock'' ) 268 dup sb-buf fs_nindir / ( fileblock'' indir-offset ) 269 indir-block swap la+ l@ ( fileblock'' indirblock ) 270 to indir-addr ( fileblock'' ) 271 \ load 2nd level indir block 272 indir-block ( fileblock'' indir-block ) 273 sb-buf dup fs_bsize l@ ( fileblock'' indir-block fs fs_bsize ) 274 swap indir-addr swap ( fileblock'' indir-block fs_bsize indiraddr fs ) 275 fsbtodb ( fileblock'' indir-block fs_bsize db ) 276 strategy ( fileblock'' nread ) 277 drop ( fileblock'' ) 278 sb-buf fs_nindir l@ mod indir-block swap la+ l@ exit 279 then 280 ." block-map: exceeded max file size" cr 281 abort 282; 283 284\ 285\ Read file into internal buffer and return pointer and len 286\ 287 2880 value cur-block \ allocated dynamically in ufs-open 2890 value cur-blocksize \ size of cur-block 290-1 value cur-blockno 2910 value cur-offset 292 293: buf-read-file ( fs -- len buf ) 294 cur-offset swap ( seekp fs ) 295 2dup blkoff ( seekp fs off ) 296 -rot 2dup lblkno ( off seekp fs block ) 297 swap 2dup cur-inode ( off seekp block fs block fs inop ) 298 swap dblksize ( off seekp block fs size ) 299 rot dup cur-blockno ( off seekp fs size block block cur ) 300 <> if ( off seekp fs size block ) 301 block-map ( off seekp fs size diskblock ) 302 dup 0= if ( off seekp fs size diskblock ) 303 over cur-block swap 0 fill ( off seekp fs size diskblock ) 304 boot-debug? if ." buf-read-file fell off end of file" cr then 305 else 306 2dup sb-buf fsbtodb cur-block -rot strategy ( off seekp fs size diskblock nread ) 307 rot 2dup <> if " buf-read-file: short read." cr abort then 308 then ( off seekp fs diskblock nread size ) 309 nip nip ( off seekp fs size ) 310 else ( off seekp fs size block block cur ) 311 2drop ( off seekp fs size ) 312 then 313\ dup cur-offset + to cur-offset \ Set up next xfer -- not done 314 nip nip swap - ( len ) 315 cur-block 316; 317 318\ 319\ Read inode into cur-inode -- uses cur-block 320\ 321 322: read-inode ( inode fs -- ) 323 twiddle ( inode fs -- inode fs ) 324 325 cur-block ( inode fs -- inode fs buffer ) 326 327 over ( inode fs buffer -- inode fs buffer fs ) 328 fs_bsize l@ ( inode fs buffer -- inode fs buffer size ) 329 330 2over ( inode fs buffer size -- inode fs buffer size inode fs ) 331 2over ( inode fs buffer size inode fs -- inode fs buffer size inode fs buffer size ) 332 2swap tuck ( inode fs buffer size inode fs buffer size -- inode fs buffer size buffer size fs inode fs ) 333 334 ino-to-fsba ( inode fs buffer size buffer size fs inode fs -- inode fs buffer size buffer size fs fsba ) 335 swap ( inode fs buffer size buffer size fs fsba -- inode fs buffer size buffer size fsba fs ) 336 fsbtodb ( inode fs buffer size buffer size fsba fs -- inode fs buffer size buffer size db ) 337 338 dup to cur-blockno ( inode fs buffer size buffer size dstart -- inode fs buffer size buffer size dstart ) 339 strategy ( inode fs buffer size buffer size dstart -- inode fs buffer size nread ) 340 <> if ." read-inode - residual" cr abort then 341 dup 2over ( inode fs buffer -- inode fs buffer buffer inode fs ) 342 ino-to-fsbo ( inode fs buffer -- inode fs buffer buffer fsbo ) 343 ufs1_dinode_SIZEOF * + ( inode fs buffer buffer fsbo -- inode fs buffer dinop ) 344 cur-inode ufs1_dinode_SIZEOF move ( inode fs buffer dinop -- inode fs buffer ) 345 \ clear out the old buffers 346 drop ( inode fs buffer -- inode fs ) 347 2drop 348; 349 350\ Identify inode type 351 352: is-dir? ( ufs1_dinode -- true:false ) di_mode w@ ifmt and ifdir = ; 353: is-symlink? ( ufs1_dinode -- true:false ) di_mode w@ ifmt and iflnk = ; 354 355 356 357\ 358\ Hunt for directory entry: 359\ 360\ repeat 361\ load a buffer 362\ while entries do 363\ if entry == name return 364\ next entry 365\ until no buffers 366\ 367 368: search-directory ( str len -- ino|0 ) 369 0 to cur-offset 370 begin cur-offset cur-inode di_size x@ < while ( str len ) 371 sb-buf buf-read-file ( str len len buf ) 372 over 0= if ." search-directory: buf-read-file zero len" cr abort then 373 swap dup cur-offset + to cur-offset ( str len buf len ) 374 2dup + nip ( str len buf bufend ) 375 swap 2swap rot ( bufend str len buf ) 376 begin dup 4 pick < while ( bufend str len buf ) 377 dup d_ino l@ 0<> if ( bufend str len buf ) 378 boot-debug? if dup dup d_name swap d_namlen c@ type cr then 379 2dup d_namlen c@ = if ( bufend str len buf ) 380 dup d_name 2over ( bufend str len buf dname str len ) 381 comp 0= if ( bufend str len buf ) 382 \ Found it -- return inode 383 d_ino l@ nip nip nip ( dino ) 384 boot-debug? if ." Found it" cr then 385 exit ( dino ) 386 then 387 then ( bufend str len buf ) 388 then ( bufend str len buf ) 389 dup d_reclen w@ + ( bufend str len nextbuf ) 390 repeat 391 drop rot drop ( str len ) 392 repeat 393 2drop 2drop 0 ( 0 ) 394; 395 396: ffs_oldcompat ( -- ) 397\ Make sure old ffs values in sb-buf are sane 398 sb-buf fs_old_npsect dup l@ sb-buf fs_old_nsect l@ max swap l! 399 sb-buf fs_old_interleave dup l@ 1 max swap l! 400 sb-buf fs_old_postblformat l@ fs_42postblfmt = if 401 8 sb-buf fs_old_nrpos l! 402 then 403 sb-buf fs_old_inodefmt l@ fs_44inodefmt < if 404 sb-buf fs_bsize l@ 405 dup ndaddr * 1- sb-buf fs_maxfilesize x! 406 niaddr 0 ?do 407 sb-buf fs_nindir l@ * dup ( sizebp sizebp -- ) 408 sb-buf fs_maxfilesize dup x@ ( sizebp sizebp *fs_maxfilesize fs_maxfilesize -- ) 409 rot ( sizebp *fs_maxfilesize fs_maxfilesize sizebp -- ) 410 + ( sizebp *fs_maxfilesize new_fs_maxfilesize -- ) 411 swap x! ( sizebp -- ) 412 loop drop ( -- ) 413 sb-buf dup fs_bmask l@ not swap fs_qbmask x! 414 sb-buf dup fs_fmask l@ not swap fs_qfmask x! 415 then 416; 417 418: read-super ( sector -- ) 4190 " seek" boot-ihandle $call-method 420 -1 = if 421 ." Seek failed" cr 422 abort 423 then 424 sb-buf sbsize " read" boot-ihandle $call-method 425 dup sbsize <> if 426 ." Read of superblock failed" cr 427 ." requested" space sbsize . 428 ." actual" space . cr 429 abort 430 else 431 drop 432 then 433; 434 435: ufs-open ( bootpath,len -- ) 436 boot-ihandle -1 = if 437 over cif-open dup 0= if ( boot-path len ihandle? ) 438 ." Could not open device" space type cr 439 abort 440 then ( boot-path len ihandle ) 441 to boot-ihandle \ Save ihandle to boot device 442 then 2drop 443 force-raid if 444 boot-debug? if ." Force RAID superblock read" cr then 445 rf_protected dup to raid-offset 446 dev_bsize * sboff + read-super 447 sb-buf fs_magic l@ fs_magic_value <> if 448 ." Invalid superblock magic" cr 449 abort 450 then 451 else 452 boot-debug? if ." Normal superblock read" cr then 453 sboff read-super 454 sb-buf fs_magic l@ fs_magic_value <> if 455 boot-debug? if ." RAID superblock read" cr then 456 true to force-raid 457 rf_protected dup to raid-offset 458 dev_bsize * sboff + read-super 459 sb-buf fs_magic l@ fs_magic_value <> if 460 ." Invalid superblock magic" cr 461 abort 462 then 463 then 464 then 465 sb-buf fs_bsize l@ dup maxbsize > if 466 ." Superblock bsize" space . ." too large" cr 467 abort 468 then 469 dup fs_SIZEOF < if 470 ." Superblock bsize < size of superblock" cr 471 abort 472 then 473 ffs_oldcompat ( fs_bsize -- fs_bsize ) 474 dup to cur-blocksize alloc-mem to cur-block \ Allocate cur-block 475 boot-debug? if ." ufs-open complete" cr then 476; 477 478: ufs-close ( -- ) 479 boot-ihandle dup -1 <> if 480 cif-close -1 to boot-ihandle 481 then 482 cur-block 0<> if 483 cur-block cur-blocksize free-mem 484 then 485; 486 487: boot-path ( -- boot-path ) 488 " bootpath" chosen-phandle get-package-property if 489 ." Could not find bootpath in /chosen" cr 490 abort 491 else 492 decode-string 2swap 2drop 493 then 494; 495 496: boot-args ( -- boot-args ) 497 " bootargs" chosen-phandle get-package-property if 498 ." Could not find bootargs in /chosen" cr 499 abort 500 else 501 decode-string 2swap 2drop 502 then 503; 504 5052000 buffer: boot-path-str 5062000 buffer: boot-path-tmp 507 508: split-path ( path len -- right len left len ) 509\ Split a string at the `/' 510 begin 511 dup -rot ( oldlen right len left ) 512 ascii / left-parse-string ( oldlen right len left len ) 513 dup 0<> if 4 roll drop exit then 514 2drop ( oldlen right len ) 515 rot over = ( right len diff ) 516 until 517; 518 519: find-file ( load-file len -- ) 520 rootino dup sb-buf read-inode ( load-file len -- load-file len ino ) 521 -rot ( load-file len ino -- pino load-file len ) 522 \ 523 \ For each path component 524 \ 525 begin split-path dup 0<> while ( pino right len left len -- ) 526 cur-inode is-dir? not if ." Inode not directory" cr false exit then 527 boot-debug? if ." Looking for" space 2dup type space ." in directory..." cr then 528 search-directory ( pino right len left len -- pino right len ino|false ) 529 dup 0= if ." Bad path" cr abort then ( pino right len cino ) 530 sb-buf read-inode ( pino right len ) 531 cur-inode is-symlink? if \ Symlink -- follow the damn thing 532 \ Save path in boot-path-tmp 533 boot-path-tmp strmov ( pino new-right len ) 534 535 \ Now deal with symlink 536 cur-inode di_size x@ ( pino right len linklen ) 537 dup sb-buf fs_maxsymlinklen l@ ( pino right len linklen linklen maxlinklen ) 538 < if \ Now join the link to the path 539 cur-inode di_db l@ ( pino right len linklen linkp ) 540 swap boot-path-str strmov ( pino right len new-linkp linklen ) 541 else \ Read file for symlink -- Ugh 542 \ Read link into boot-path-str 543 boot-path-str dup sb-buf fs_bsize l@ 544 0 block-map ( pino right len linklen boot-path-str bsize blockno ) 545 strategy drop swap ( pino right len boot-path-str linklen ) 546 then ( pino right len linkp linklen ) 547 \ Concatenate the two paths 548 strcat ( pino new-right newlen ) 549 swap dup c@ ascii / = if \ go to root inode? 550 rot drop rootino -rot ( rino len right ) 551 then 552 rot dup sb-buf read-inode ( len right pino ) 553 -rot swap ( pino right len ) 554 then ( pino right len ) 555 repeat 556 2drop drop 557 true 558; 559 560: read-file ( size addr -- ) 561 \ Read x bytes from a file to buffer 562 begin over 0> while 563 cur-offset cur-inode di_size x@ > if ." read-file EOF exceeded" cr abort then 564 sb-buf buf-read-file ( size addr len buf ) 565 over 2over drop swap ( size addr len buf addr len ) 566 move ( size addr len ) 567 dup cur-offset + to cur-offset ( size len newaddr ) 568 tuck + ( size len newaddr ) 569 -rot - swap ( newaddr newsize ) 570 repeat 571 2drop 572; 573 574\ 575\ According to the 1275 addendum for SPARC processors: 576\ Default load-base is 0x4000. At least 0x8.0000 or 577\ 512KB must be available at that address. 578\ 579\ The Fcode bootblock can take up up to 8KB (O.K., 7.5KB) 580\ so load programs at 0x4000 + 0x2000=> 0x6000 581\ 582 583h# 6000 constant loader-base 584 585\ 586\ Elf support -- find the load addr 587\ 588 589: is-elf? ( hdr -- res? ) h# 7f454c46 = ; 590 591\ 592\ Finally we finish it all off 593\ 594 595: load-file-signon ( load-file len boot-path len -- load-file len boot-path len ) 596 ." Loading file" space 2over type cr ." from device" space 2dup type cr 597; 598 599: load-file-print-size ( size -- size ) 600 ." Loading" space dup . space ." bytes of file..." cr 601; 602 603: load-file ( load-file len boot-path len -- load-base ) 604 boot-debug? if load-file-signon then 605 the-file file_SIZEOF 0 fill \ Clear out file structure 606 \ copy "load-file len boot-path len" in case we need to set "force-raid" 607 2over 2over ( load-file len boot-path len load-file len boot-path len ) 608 ufs-open ( load-file len boot-path len load-file len ) 609 find-file not if ( load-file len boot-path len ) 610 force-raid not if 611 true to force-raid ( ) 612 ufs-close 613 2drop 2drop drop ( load-file len boot-path len ) 614 ufs-open ( load-file len ) 615 find-file ( true:false ) 616 drop 617 else 618 abort 619 then 620 else 621 \ We didn't set "force-raid", discard the copies 622 2drop 2drop ( ) 623 then 624 625 \ 626 \ Now we've found the file we should read it in in one big hunk 627 \ 628 629 cur-inode di_size x@ ( file-len ) 630 dup " to file-size" evaluate ( file-len ) 631 boot-debug? if load-file-print-size then 632 0 to cur-offset 633 loader-base ( buf-len addr ) 634 2dup read-file ( buf-len addr ) 635 ufs-close ( buf-len addr ) 636 dup is-elf? if ." load-file: not an elf executable" cr abort then 637 638 \ Luckily the prom should be able to handle ELF executables by itself 639 640 nip ( addr ) 641; 642 643: do-boot ( bootfile -- ) 644 ." NetBSD IEEE 1275 Bootblock" cr 645 boot-path load-file ( -- load-base ) 646 dup 0<> if " to load-base init-program" evaluate then 647; 648 649 650boot-args ascii V strchr 0<> swap drop if 651 true to boot-debug? 652then 653 654boot-args ascii D strchr 0= swap drop if 655 " /ofwboot" do-boot 656then exit 657 658 659