bootblk.fth revision 1.3
11.3Seeh\ $NetBSD: bootblk.fth,v 1.3 2001/08/15 20:10:24 eeh Exp $ 21.1Smrg\ 31.1Smrg\ IEEE 1275 Open Firmware Boot Block 41.1Smrg\ 51.1Smrg\ Parses disklabel and UFS and loads the file called `ofwboot' 61.1Smrg\ 71.1Smrg\ 81.1Smrg\ Copyright (c) 1998 Eduardo Horvath. 91.1Smrg\ All rights reserved. 101.1Smrg\ 111.1Smrg\ Redistribution and use in source and binary forms, with or without 121.1Smrg\ modification, are permitted provided that the following conditions 131.1Smrg\ are met: 141.1Smrg\ 1. Redistributions of source code must retain the above copyright 151.1Smrg\ notice, this list of conditions and the following disclaimer. 161.1Smrg\ 2. Redistributions in binary form must reproduce the above copyright 171.1Smrg\ notice, this list of conditions and the following disclaimer in the 181.1Smrg\ documentation and/or other materials provided with the distribution. 191.1Smrg\ 3. All advertising materials mentioning features or use of this software 201.1Smrg\ must display the following acknowledgement: 211.1Smrg\ This product includes software developed by Eduardo Horvath. 221.1Smrg\ 4. The name of the author may not be used to endorse or promote products 231.2Swiz\ derived from this software without specific prior written permission 241.1Smrg\ 251.1Smrg\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 261.1Smrg\ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 271.1Smrg\ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 281.1Smrg\ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 291.1Smrg\ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 301.1Smrg\ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 311.1Smrg\ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 321.1Smrg\ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 331.1Smrg\ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 341.1Smrg\ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 351.1Smrg\ 361.1Smrg 371.1Smrgoffset16 381.1Smrghex 391.1Smrgheaders 401.1Smrg 411.1Smrgfalse value boot-debug? 421.1Smrg 431.1Smrg\ 441.1Smrg\ First some housekeeping: Open /chosen and set up vectors into 451.1Smrg\ client-services 461.1Smrg 471.1Smrg" /chosen" find-package 0= if ." Cannot find /chosen" 0 then 481.1Smrgconstant chosen-phandle 491.1Smrg 501.1Smrg" /openprom/client-services" find-package 0= if 511.1Smrg ." Cannot find client-services" cr abort 521.1Smrgthen constant cif-phandle 531.1Smrg 541.1Smrgdefer cif-claim ( align size virt -- base ) 551.1Smrgdefer cif-release ( size virt -- ) 561.1Smrgdefer cif-open ( cstr -- ihandle|0 ) 571.1Smrgdefer cif-close ( ihandle -- ) 581.1Smrgdefer cif-read ( len adr ihandle -- #read ) 591.1Smrgdefer cif-seek ( low high ihandle -- -1|0|1 ) 601.1Smrg\ defer cif-peer ( phandle -- phandle ) 611.1Smrg\ defer cif-getprop ( len adr cstr phandle -- ) 621.1Smrg 631.1Smrg: find-cif-method ( method,len -- xf ) 641.1Smrg cif-phandle find-method drop 651.1Smrg; 661.1Smrg 671.1Smrg" claim" find-cif-method to cif-claim 681.1Smrg" open" find-cif-method to cif-open 691.1Smrg" close" find-cif-method to cif-close 701.1Smrg" read" find-cif-method to cif-read 711.1Smrg" seek" find-cif-method to cif-seek 721.1Smrg 731.1Smrg: twiddle ( -- ) ." ." ; \ Need to do this right. Just spit out periods for now. 741.1Smrg 751.1Smrg\ 761.1Smrg\ Support routines 771.1Smrg\ 781.1Smrg 791.1Smrg: strcmp ( s1 l1 s2 l2 -- true:false ) 801.1Smrg rot tuck <> if 3drop false exit then 811.1Smrg comp 0= 821.1Smrg; 831.1Smrg 841.1Smrg\ Move string into buffer 851.1Smrg 861.1Smrg: strmov ( s1 l1 d -- d l1 ) 871.1Smrg dup 2over swap -rot ( s1 l1 d s1 d l1 ) 881.1Smrg move ( s1 l1 d ) 891.1Smrg rot drop swap 901.1Smrg; 911.1Smrg 921.1Smrg\ Move s1 on the end of s2 and return the result 931.1Smrg 941.1Smrg: strcat ( s1 l1 s2 l2 -- d tot ) 951.1Smrg 2over swap ( s1 l1 s2 l2 l1 s1 ) 961.1Smrg 2over + rot ( s1 l1 s2 l2 s1 d l1 ) 971.1Smrg move rot + ( s1 s2 len ) 981.1Smrg rot drop ( s2 len ) 991.1Smrg; 1001.1Smrg 1011.1Smrg: strchr ( s1 l1 c -- s2 l2 ) 1021.1Smrg begin 1031.1Smrg dup 2over 0= if ( s1 l1 c c s1 ) 1041.1Smrg 2drop drop exit then 1051.1Smrg c@ = if ( s1 l1 c ) 1061.1Smrg drop exit then 1071.1Smrg -rot /c - swap ca1+ ( c l2 s2 ) 1081.1Smrg swap rot 1091.1Smrg again 1101.1Smrg; 1111.1Smrg 1121.1Smrg 1131.1Smrg: cstr ( ptr -- str len ) 1141.1Smrg dup 1151.1Smrg begin dup c@ 0<> while + repeat 1161.1Smrg over - 1171.1Smrg; 1181.1Smrg 1191.1Smrg\ 1201.1Smrg\ BSD FFS parameters 1211.1Smrg\ 1221.1Smrg 1231.1Smrgfload assym.fth.h 1241.1Smrg 1251.1Smrgsbsize buffer: sb-buf 1261.1Smrg-1 value boot-ihandle 1271.1Smrgdev_bsize value bsize 1281.3Seeh0 value raid-offset \ Offset if it's a raid-frame partition 1291.1Smrg 1301.1Smrg: strategy ( addr size start -- nread ) 1311.3Seeh raid-offset + bsize * 0 " seek" boot-ihandle $call-method 1321.1Smrg -1 = if 1331.1Smrg ." strategy: Seek failed" cr 1341.1Smrg abort 1351.1Smrg then 1361.1Smrg " read" boot-ihandle $call-method 1371.1Smrg; 1381.1Smrg 1391.1Smrg\ 1401.1Smrg\ Cylinder group macros 1411.1Smrg\ 1421.1Smrg 1431.1Smrg: cgbase ( cg fs -- cgbase ) fs_fpg l@ * ; 1441.1Smrg: cgstart ( cg fs -- cgstart ) 1451.1Smrg 2dup fs_cgmask l@ not and ( cg fs stuff -- ) 1461.1Smrg over fs_cgoffset l@ * -rot ( stuffcg fs -- ) 1471.1Smrg cgbase + 1481.1Smrg; 1491.1Smrg: cgdmin ( cg fs -- 1st-data-block ) dup fs_dblkno l@ -rot cgstart + ; 1501.1Smrg: cgimin ( cg fs -- inode-block ) dup fs_iblkno l@ -rot cgstart + ; 1511.1Smrg: cgsblock ( cg fs -- super-block ) dup fs_sblkno l@ -rot cgstart + ; 1521.1Smrg: cgstod ( cg fs -- cg-block ) dup fs_cblkno l@ -rot cgstart + ; 1531.1Smrg 1541.1Smrg\ 1551.1Smrg\ Block and frag position macros 1561.1Smrg\ 1571.1Smrg 1581.1Smrg: blkoff ( pos fs -- off ) fs_qbmask x@ and ; 1591.1Smrg: fragoff ( pos fs -- off ) fs_qfmask x@ and ; 1601.1Smrg: lblktosize ( blk fs -- off ) fs_bshift l@ << ; 1611.1Smrg: lblkno ( pos fs -- off ) fs_bshift l@ >> ; 1621.1Smrg: numfrags ( pos fs -- off ) fs_fshift l@ >> ; 1631.1Smrg: blkroundup ( pos fs -- off ) dup fs_bmask l@ -rot fs_qbmask x@ + and ; 1641.1Smrg: fragroundup ( pos fs -- off ) dup fs_fmask l@ -rot fs_qfmask x@ + and ; 1651.1Smrg\ : fragroundup ( pos fs -- off ) tuck fs_qfmask x@ + swap fs_fmask l@ and ; 1661.1Smrg: fragstoblks ( pos fs -- off ) fs_fragshift l@ >> ; 1671.1Smrg: blkstofrags ( blk fs -- frag ) fs_fragshift l@ << ; 1681.1Smrg: fragnum ( fsb fs -- off ) fs_frag l@ 1- and ; 1691.1Smrg: blknum ( fsb fs -- off ) fs_frag l@ 1- not and ; 1701.1Smrg: dblksize ( lbn dino fs -- size ) 1711.1Smrg -rot ( fs lbn dino ) 1721.1Smrg di_size x@ ( fs lbn di_size ) 1731.1Smrg -rot dup 1+ ( di_size fs lbn lbn+1 ) 1741.1Smrg 2over fs_bshift l@ ( di_size fs lbn lbn+1 di_size b_shift ) 1751.1Smrg rot swap << >= ( di_size fs lbn res1 ) 1761.1Smrg swap ndaddr >= or if ( di_size fs ) 1771.1Smrg swap drop fs_bsize l@ exit ( size ) 1781.1Smrg then tuck blkoff swap fragroundup ( size ) 1791.1Smrg; 1801.1Smrg 1811.1Smrg 1821.1Smrg: ino-to-cg ( ino fs -- cg ) fs_ipg l@ / ; 1831.1Smrg: ino-to-fsbo ( ino fs -- fsb0 ) fs_inopb l@ mod ; 1841.1Smrg: ino-to-fsba ( ino fs -- ba ) \ Need to remove the stupid stack diags someday 1851.1Smrg 2dup ( ino fs ino fs ) 1861.1Smrg ino-to-cg ( ino fs cg ) 1871.1Smrg over ( ino fs cg fs ) 1881.1Smrg cgimin ( ino fs inode-blk ) 1891.1Smrg -rot ( inode-blk ino fs ) 1901.1Smrg tuck ( inode-blk fs ino fs ) 1911.1Smrg fs_ipg l@ ( inode-blk fs ino ipg ) 1921.1Smrg mod ( inode-blk fs mod ) 1931.1Smrg swap ( inode-blk mod fs ) 1941.1Smrg dup ( inode-blk mod fs fs ) 1951.1Smrg fs_inopb l@ ( inode-blk mod fs inopb ) 1961.1Smrg rot ( inode-blk fs inopb mod ) 1971.1Smrg swap ( inode-blk fs mod inopb ) 1981.1Smrg / ( inode-blk fs div ) 1991.1Smrg swap ( inode-blk div fs ) 2001.1Smrg blkstofrags ( inode-blk frag ) 2011.1Smrg + 2021.1Smrg; 2031.1Smrg: fsbtodb ( fsb fs -- db ) fs_fsbtodb l@ << ; 2041.1Smrg 2051.1Smrg\ 2061.1Smrg\ File stuff 2071.1Smrg\ 2081.1Smrg 2091.1Smrgniaddr /w* constant narraysize 2101.1Smrg 2111.1Smrgstruct 2121.1Smrg 8 field >f_ihandle \ device handle 2131.1Smrg 8 field >f_seekp \ seek pointer 2141.1Smrg 8 field >f_fs \ pointer to super block 2151.1Smrg dinode_SIZEOF field >f_di \ copy of on-disk inode 2161.1Smrg 8 field >f_buf \ buffer for data block 2171.1Smrg 4 field >f_buf_size \ size of data block 2181.1Smrg 4 field >f_buf_blkno \ block number of data block 2191.1Smrgconstant file_SIZEOF 2201.1Smrg 2211.1Smrgfile_SIZEOF buffer: the-file 2221.1Smrgsb-buf the-file >f_fs x! 2231.1Smrg 2241.1Smrgdinode_SIZEOF buffer: cur-inode 2251.1Smrgh# 2000 buffer: indir-block 2261.1Smrg-1 value indir-addr 2271.1Smrg 2281.1Smrg\ 2291.1Smrg\ Translate a fileblock to a disk block 2301.1Smrg\ 2311.1Smrg\ We only allow single indirection 2321.1Smrg\ 2331.1Smrg 2341.1Smrg: block-map ( fileblock -- diskblock ) 2351.1Smrg \ Direct block? 2361.1Smrg dup ndaddr < if ( fileblock ) 2371.1Smrg cur-inode di_db ( arr-indx arr-start ) 2381.1Smrg swap la+ l@ exit ( diskblock ) 2391.1Smrg then ( fileblock ) 2401.1Smrg ndaddr - ( fileblock' ) 2411.1Smrg \ Now we need to check the indirect block 2421.1Smrg dup sb-buf fs_nindir l@ < if ( fileblock' ) 2431.1Smrg cur-inode di_ib l@ dup ( fileblock' indir-block indir-block ) 2441.1Smrg indir-addr <> if ( fileblock' indir-block ) 2451.1Smrg to indir-addr ( fileblock' ) 2461.1Smrg indir-block ( fileblock' indir-block ) 2471.1Smrg sb-buf dup fs_bsize l@ ( fileblock' indir-block fs fs_bsize ) 2481.1Smrg swap indir-addr swap ( fileblock' indir-block fs_bsize indiraddr fs ) 2491.1Smrg fsbtodb ( fileblock' indir-block fs_bsize db ) 2501.1Smrg strategy ( fileblock' nread ) 2511.1Smrg then ( fileblock' nread|indir-block ) 2521.1Smrg drop \ Really should check return value 2531.1Smrg indir-block swap la+ l@ exit 2541.1Smrg then 2551.1Smrg dup sb-buf fs_nindir - ( fileblock'' ) 2561.1Smrg \ Now try 2nd level indirect block -- just read twice 2571.1Smrg dup sb-buf fs_nindir l@ dup * < if ( fileblock'' ) 2581.1Smrg cur-inode di_ib 1 la+ l@ ( fileblock'' indir2-block ) 2591.1Smrg to indir-addr ( fileblock'' ) 2601.1Smrg \ load 1st level indir block 2611.1Smrg indir-block ( fileblock'' indir-block ) 2621.1Smrg sb-buf dup fs_bsize l@ ( fileblock'' indir-block fs fs_bsize ) 2631.1Smrg swap indir-addr swap ( fileblock'' indir-block fs_bsize indiraddr fs ) 2641.1Smrg fsbtodb ( fileblock'' indir-block fs_bsize db ) 2651.1Smrg strategy ( fileblock'' nread ) 2661.1Smrg drop ( fileblock'' ) 2671.1Smrg dup sb-buf fs_nindir / ( fileblock'' indir-offset ) 2681.1Smrg indir-block swap la+ l@ ( fileblock'' indirblock ) 2691.1Smrg to indir-addr ( fileblock'' ) 2701.1Smrg \ load 2nd level indir block 2711.1Smrg indir-block ( fileblock'' indir-block ) 2721.1Smrg sb-buf dup fs_bsize l@ ( fileblock'' indir-block fs fs_bsize ) 2731.1Smrg swap indir-addr swap ( fileblock'' indir-block fs_bsize indiraddr fs ) 2741.1Smrg fsbtodb ( fileblock'' indir-block fs_bsize db ) 2751.1Smrg strategy ( fileblock'' nread ) 2761.1Smrg drop ( fileblock'' ) 2771.1Smrg sb-buf fs_nindir l@ mod indir-block swap la+ l@ exit 2781.1Smrg then 2791.1Smrg ." block-map: exceeded max file size" cr 2801.1Smrg abort 2811.1Smrg; 2821.1Smrg 2831.1Smrg\ 2841.1Smrg\ Read file into internal buffer and return pointer and len 2851.1Smrg\ 2861.1Smrg 2871.1Smrg2000 buffer: cur-block \ Why do dynamic allocation? 2881.1Smrg-1 value cur-blockno 2891.1Smrg0 value cur-offset 2901.1Smrg 2911.1Smrg: buf-read-file ( fs -- len buf ) 2921.1Smrg cur-offset swap ( seekp fs ) 2931.1Smrg 2dup blkoff ( seekp fs off ) 2941.1Smrg -rot 2dup lblkno ( off seekp fs block ) 2951.1Smrg swap 2dup cur-inode ( off seekp block fs block fs inop ) 2961.1Smrg swap dblksize ( off seekp block fs size ) 2971.1Smrg rot dup cur-blockno ( off seekp fs size block block cur ) 2981.1Smrg <> if ( off seekp fs size block ) 2991.1Smrg block-map ( off seekp fs size diskblock ) 3001.1Smrg dup 0= if ( off seekp fs size diskblock ) 3011.1Smrg over cur-block swap 0 fill ( off seekp fs size diskblock ) 3021.1Smrg boot-debug? if ." buf-read-file fell off end of file" cr then 3031.1Smrg else 3041.1Smrg 2dup sb-buf fsbtodb cur-block -rot strategy ( off seekp fs size diskblock nread ) 3051.1Smrg rot 2dup <> if " buf-read-file: short read." cr abort then 3061.1Smrg then ( off seekp fs diskblock nread size ) 3071.1Smrg nip nip ( off seekp fs size ) 3081.1Smrg else ( off seekp fs size block block cur ) 3091.1Smrg 2drop ( off seekp fs size ) 3101.1Smrg then 3111.1Smrg\ dup cur-offset + to cur-offset \ Set up next xfer -- not done 3121.1Smrg nip nip swap - ( len ) 3131.1Smrg cur-block 3141.1Smrg; 3151.1Smrg 3161.1Smrg\ 3171.1Smrg\ Read inode into cur-inode -- uses cur-block 3181.1Smrg\ 3191.1Smrg 3201.1Smrg: read-inode ( inode fs -- ) 3211.1Smrg twiddle ( inode fs -- inode fs ) 3221.1Smrg 3231.1Smrg cur-block ( inode fs -- inode fs buffer ) 3241.1Smrg 3251.1Smrg over ( inode fs buffer -- inode fs buffer fs ) 3261.1Smrg fs_bsize l@ ( inode fs buffer -- inode fs buffer size ) 3271.1Smrg 3281.1Smrg 2over ( inode fs buffer size -- inode fs buffer size inode fs ) 3291.1Smrg 2over ( inode fs buffer size inode fs -- inode fs buffer size inode fs buffer size ) 3301.1Smrg 2swap tuck ( inode fs buffer size inode fs buffer size -- inode fs buffer size buffer size fs inode fs ) 3311.1Smrg 3321.1Smrg ino-to-fsba ( inode fs buffer size buffer size fs inode fs -- inode fs buffer size buffer size fs fsba ) 3331.1Smrg swap ( inode fs buffer size buffer size fs fsba -- inode fs buffer size buffer size fsba fs ) 3341.1Smrg fsbtodb ( inode fs buffer size buffer size fsba fs -- inode fs buffer size buffer size db ) 3351.1Smrg 3361.1Smrg dup to cur-blockno ( inode fs buffer size buffer size dstart -- inode fs buffer size buffer size dstart ) 3371.1Smrg strategy ( inode fs buffer size buffer size dstart -- inode fs buffer size nread ) 3381.1Smrg <> if ." read-inode - residual" cr abort then 3391.1Smrg dup 2over ( inode fs buffer -- inode fs buffer buffer inode fs ) 3401.1Smrg ino-to-fsbo ( inode fs buffer -- inode fs buffer buffer fsbo ) 3411.1Smrg dinode_SIZEOF * + ( inode fs buffer buffer fsbo -- inode fs buffer dinop ) 3421.1Smrg cur-inode dinode_SIZEOF move ( inode fs buffer dinop -- inode fs buffer ) 3431.1Smrg \ clear out the old buffers 3441.1Smrg drop ( inode fs buffer -- inode fs ) 3451.1Smrg 2drop 3461.1Smrg; 3471.1Smrg 3481.1Smrg\ Identify inode type 3491.1Smrg 3501.1Smrg: is-dir? ( dinode -- true:false ) di_mode w@ ifmt and ifdir = ; 3511.1Smrg: is-symlink? ( dinode -- true:false ) di_mode w@ ifmt and iflnk = ; 3521.1Smrg 3531.1Smrg 3541.1Smrg 3551.1Smrg\ 3561.1Smrg\ Hunt for directory entry: 3571.1Smrg\ 3581.1Smrg\ repeat 3591.1Smrg\ load a buffer 3601.1Smrg\ while entries do 3611.1Smrg\ if entry == name return 3621.1Smrg\ next entry 3631.1Smrg\ until no buffers 3641.1Smrg\ 3651.1Smrg 3661.1Smrg: search-directory ( str len -- ino|0 ) 3671.1Smrg 0 to cur-offset 3681.1Smrg begin cur-offset cur-inode di_size x@ < while ( str len ) 3691.1Smrg sb-buf buf-read-file ( str len len buf ) 3701.1Smrg over 0= if ." search-directory: buf-read-file zero len" cr abort then 3711.1Smrg swap dup cur-offset + to cur-offset ( str len buf len ) 3721.1Smrg 2dup + nip ( str len buf bufend ) 3731.1Smrg swap 2swap rot ( bufend str len buf ) 3741.1Smrg begin dup 4 pick < while ( bufend str len buf ) 3751.1Smrg dup d_ino l@ 0<> if ( bufend str len buf ) 3761.1Smrg boot-debug? if dup dup d_name swap d_namlen c@ type cr then 3771.1Smrg 2dup d_namlen c@ = if ( bufend str len buf ) 3781.1Smrg dup d_name 2over ( bufend str len buf dname str len ) 3791.1Smrg comp 0= if ( bufend str len buf ) 3801.1Smrg \ Found it -- return inode 3811.1Smrg d_ino l@ nip nip nip ( dino ) 3821.1Smrg boot-debug? if ." Found it" cr then 3831.1Smrg exit ( dino ) 3841.1Smrg then 3851.1Smrg then ( bufend str len buf ) 3861.1Smrg then ( bufend str len buf ) 3871.1Smrg dup d_reclen w@ + ( bufend str len nextbuf ) 3881.1Smrg repeat 3891.1Smrg drop rot drop ( str len ) 3901.1Smrg repeat 3911.1Smrg 2drop 2drop 0 ( 0 ) 3921.1Smrg; 3931.1Smrg 3941.1Smrg: ffs_oldcompat ( -- ) 3951.1Smrg\ Make sure old ffs values in sb-buf are sane 3961.1Smrg sb-buf fs_npsect dup l@ sb-buf fs_nsect l@ max swap l! 3971.1Smrg sb-buf fs_interleave dup l@ 1 max swap l! 3981.1Smrg sb-buf fs_postblformat l@ fs_42postblfmt = if 3991.1Smrg 8 sb-buf fs_nrpos l! 4001.1Smrg then 4011.1Smrg sb-buf fs_inodefmt l@ fs_44inodefmt < if 4021.1Smrg sb-buf fs_bsize l@ 4031.1Smrg dup ndaddr * 1- sb-buf fs_maxfilesize x! 4041.1Smrg niaddr 0 ?do 4051.1Smrg sb-buf fs_nindir l@ * dup ( sizebp sizebp -- ) 4061.1Smrg sb-buf fs_maxfilesize dup x@ ( sizebp sizebp *fs_maxfilesize fs_maxfilesize -- ) 4071.1Smrg rot ( sizebp *fs_maxfilesize fs_maxfilesize sizebp -- ) 4081.1Smrg + ( sizebp *fs_maxfilesize new_fs_maxfilesize -- ) swap x! ( sizebp -- ) 4091.1Smrg loop drop ( -- ) 4101.1Smrg sb-buf dup fs_bmask l@ not swap fs_qbmask x! 4111.1Smrg sb-buf dup fs_fmask l@ not swap fs_qfmask x! 4121.1Smrg then 4131.1Smrg; 4141.1Smrg 4151.3Seeh: read-super ( sector -- ) 4161.3Seeh0 " seek" boot-ihandle $call-method 4171.1Smrg -1 = if 4181.1Smrg ." Seek failed" cr 4191.1Smrg abort 4201.1Smrg then 4211.1Smrg sb-buf sbsize " read" boot-ihandle $call-method 4221.1Smrg dup sbsize <> if 4231.1Smrg ." Read of superblock failed" cr 4241.1Smrg ." requested" space sbsize . 4251.1Smrg ." actual" space . cr 4261.1Smrg abort 4271.1Smrg else 4281.1Smrg drop 4291.1Smrg then 4301.3Seeh; 4311.3Seeh 4321.3Seeh: ufs-open ( bootpath,len -- ) 4331.3Seeh boot-ihandle -1 = if 4341.3Seeh over cif-open dup 0= if ( boot-path len ihandle? ) 4351.3Seeh ." Could not open device" space type cr 4361.3Seeh abort 4371.3Seeh then ( boot-path len ihandle ) 4381.3Seeh to boot-ihandle \ Save ihandle to boot device 4391.3Seeh then 2drop 4401.3Seeh sboff read-super 4411.1Smrg sb-buf fs_magic l@ fs_magic_value <> if 4421.3Seeh 64 dup to raid-offset 4431.3Seeh dev_bsize * sboff + read-super 4441.3Seeh sb-buf fs_magic l@ fs_magic_value <> if 4451.3Seeh ." Invalid superblock magic" cr 4461.3Seeh abort 4471.3Seeh then 4481.1Smrg then 4491.1Smrg sb-buf fs_bsize l@ dup maxbsize > if 4501.1Smrg ." Superblock bsize" space . ." too large" cr 4511.1Smrg abort 4521.1Smrg then 4531.1Smrg fs_SIZEOF < if 4541.1Smrg ." Superblock bsize < size of superblock" cr 4551.1Smrg abort 4561.1Smrg then 4571.1Smrg ffs_oldcompat 4581.1Smrg boot-debug? if ." ufs-open complete" cr then 4591.1Smrg; 4601.1Smrg 4611.1Smrg: ufs-close ( -- ) 4621.1Smrg boot-ihandle dup -1 <> if 4631.1Smrg cif-close -1 to boot-ihandle 4641.1Smrg then 4651.1Smrg; 4661.1Smrg 4671.1Smrg: boot-path ( -- boot-path ) 4681.1Smrg " bootpath" chosen-phandle get-package-property if 4691.1Smrg ." Could not find bootpath in /chosen" cr 4701.1Smrg abort 4711.1Smrg else 4721.1Smrg decode-string 2swap 2drop 4731.1Smrg then 4741.1Smrg; 4751.1Smrg 4761.1Smrg: boot-args ( -- boot-args ) 4771.1Smrg " bootargs" chosen-phandle get-package-property if 4781.1Smrg ." Could not find bootargs in /chosen" cr 4791.1Smrg abort 4801.1Smrg else 4811.1Smrg decode-string 2swap 2drop 4821.1Smrg then 4831.1Smrg; 4841.1Smrg 4851.1Smrg2000 buffer: boot-path-str 4861.1Smrg2000 buffer: boot-path-tmp 4871.1Smrg 4881.1Smrg: split-path ( path len -- right len left len ) 4891.1Smrg\ Split a string at the `/' 4901.1Smrg begin 4911.1Smrg dup -rot ( oldlen right len left ) 4921.1Smrg ascii / left-parse-string ( oldlen right len left len ) 4931.1Smrg dup 0<> if 4 roll drop exit then 4941.1Smrg 2drop ( oldlen right len ) 4951.1Smrg rot over = ( right len diff ) 4961.1Smrg until 4971.1Smrg; 4981.1Smrg 4991.1Smrg: find-file ( load-file len -- ) 5001.1Smrg rootino dup sb-buf read-inode ( load-file len -- load-file len ino ) 5011.1Smrg -rot ( load-file len ino -- pino load-file len ) 5021.1Smrg \ 5031.1Smrg \ For each path component 5041.1Smrg \ 5051.1Smrg begin split-path dup 0<> while ( pino right len left len -- ) 5061.1Smrg cur-inode is-dir? not if ." Inode not directory" cr abort then 5071.1Smrg boot-debug? if ." Looking for" space 2dup type space ." in directory..." cr then 5081.1Smrg search-directory ( pino right len left len -- pino right len ino|false ) 5091.1Smrg dup 0= if ." Bad path" cr abort then ( pino right len cino ) 5101.1Smrg sb-buf read-inode ( pino right len ) 5111.1Smrg cur-inode is-symlink? if \ Symlink -- follow the damn thing 5121.1Smrg \ Save path in boot-path-tmp 5131.1Smrg boot-path-tmp strmov ( pino new-right len ) 5141.1Smrg 5151.1Smrg \ Now deal with symlink 5161.1Smrg cur-inode di_size x@ ( pino right len linklen ) 5171.1Smrg dup sb-buf fs_maxsymlinklen l@ ( pino right len linklen linklen maxlinklen ) 5181.1Smrg < if \ Now join the link to the path 5191.1Smrg cur-inode di_shortlink l@ ( pino right len linklen linkp ) 5201.1Smrg swap boot-path-str strmov ( pino right len new-linkp linklen ) 5211.1Smrg else \ Read file for symlink -- Ugh 5221.1Smrg \ Read link into boot-path-str 5231.1Smrg boot-path-str dup sb-buf fs_bsize l@ 5241.1Smrg 0 block-map ( pino right len linklen boot-path-str bsize blockno ) 5251.1Smrg strategy drop swap ( pino right len boot-path-str linklen ) 5261.1Smrg then ( pino right len linkp linklen ) 5271.1Smrg \ Concatenate the two paths 5281.1Smrg strcat ( pino new-right newlen ) 5291.1Smrg swap dup c@ ascii / = if \ go to root inode? 5301.1Smrg rot drop rootino -rot ( rino len right ) 5311.1Smrg then 5321.1Smrg rot dup sb-buf read-inode ( len right pino ) 5331.1Smrg -rot swap ( pino right len ) 5341.1Smrg then ( pino right len ) 5351.1Smrg repeat 5361.1Smrg 2drop drop 5371.1Smrg; 5381.1Smrg 5391.1Smrg: read-file ( size addr -- ) 5401.1Smrg \ Read x bytes from a file to buffer 5411.1Smrg begin over 0> while 5421.1Smrg cur-offset cur-inode di_size x@ > if ." read-file EOF exceeded" cr abort then 5431.1Smrg sb-buf buf-read-file ( size addr len buf ) 5441.1Smrg over 2over drop swap ( size addr len buf addr len ) 5451.1Smrg move ( size addr len ) 5461.1Smrg dup cur-offset + to cur-offset ( size len newaddr ) 5471.1Smrg tuck + ( size len newaddr ) 5481.1Smrg -rot - swap ( newaddr newsize ) 5491.1Smrg repeat 5501.1Smrg 2drop 5511.1Smrg; 5521.1Smrg 5531.1Smrgh# 5000 constant loader-base 5541.1Smrg 5551.1Smrg\ 5561.1Smrg\ Elf support -- find the load addr 5571.1Smrg\ 5581.1Smrg 5591.1Smrg: is-elf? ( hdr -- res? ) h# 7f454c46 = ; 5601.1Smrg 5611.1Smrg\ 5621.1Smrg\ Finally we finish it all off 5631.1Smrg\ 5641.1Smrg 5651.1Smrg: load-file-signon ( load-file len boot-path len -- load-file len boot-path len ) 5661.1Smrg ." Loading file" space 2over type cr ." from device" space 2dup type cr 5671.1Smrg; 5681.1Smrg 5691.1Smrg: load-file-print-size ( size -- size ) 5701.1Smrg ." Loading" space dup . space ." bytes of file..." cr 5711.1Smrg; 5721.1Smrg 5731.1Smrg: load-file ( load-file len boot-path len -- load-base ) 5741.1Smrg boot-debug? if load-file-signon then 5751.1Smrg the-file file_SIZEOF 0 fill \ Clear out file structure 5761.1Smrg ufs-open ( load-file len ) 5771.1Smrg find-file ( ) 5781.1Smrg 5791.1Smrg \ 5801.1Smrg \ Now we've found the file we should read it in in one big hunk 5811.1Smrg \ 5821.1Smrg 5831.1Smrg cur-inode di_size x@ ( file-len ) 5841.1Smrg dup " to file-size" evaluate ( file-len ) 5851.1Smrg boot-debug? if load-file-print-size then 5861.1Smrg 0 to cur-offset 5871.1Smrg loader-base ( buf-len addr ) 5881.1Smrg 2dup read-file ( buf-len addr ) 5891.1Smrg ufs-close ( buf-len addr ) 5901.1Smrg dup is-elf? if ." load-file: not an elf executable" cr abort then 5911.1Smrg 5921.1Smrg \ Luckily the prom should be able to handle ELF executables by itself 5931.1Smrg 5941.1Smrg nip ( addr ) 5951.1Smrg; 5961.1Smrg 5971.1Smrg: do-boot ( bootfile -- ) 5981.1Smrg ." NetBSD IEEE 1275 Bootblock" cr 5991.1Smrg boot-path load-file ( -- load-base ) 6001.1Smrg dup 0<> if " to load-base init-program" evaluate then 6011.1Smrg; 6021.1Smrg 6031.1Smrg 6041.1Smrgboot-args ascii V strchr 0<> swap drop if 6051.1Smrg true to boot-debug? 6061.1Smrgthen 6071.1Smrg 6081.1Smrgboot-args ascii D strchr 0= swap drop if 6091.1Smrg " /ofwboot" do-boot 6101.1Smrgthen exit 6111.1Smrg 6121.1Smrg 613