bootblk.fth revision 1.8
11.8Sjdc\ $NetBSD: bootblk.fth,v 1.8 2008/06/29 14:13:23 jdc 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.8Sjdcfalse value force-raid \ Force reads from raid offset 1301.1Smrg 1311.1Smrg: strategy ( addr size start -- nread ) 1321.3Seeh raid-offset + bsize * 0 " seek" boot-ihandle $call-method 1331.1Smrg -1 = if 1341.1Smrg ." strategy: Seek failed" cr 1351.1Smrg abort 1361.1Smrg then 1371.1Smrg " read" boot-ihandle $call-method 1381.1Smrg; 1391.1Smrg 1401.1Smrg\ 1411.1Smrg\ Cylinder group macros 1421.1Smrg\ 1431.1Smrg 1441.1Smrg: cgbase ( cg fs -- cgbase ) fs_fpg l@ * ; 1451.1Smrg: cgstart ( cg fs -- cgstart ) 1461.5She 2dup fs_old_cgmask l@ not and ( cg fs stuff -- ) 1471.5She over fs_old_cgoffset l@ * -rot ( stuffcg fs -- ) 1481.1Smrg cgbase + 1491.1Smrg; 1501.1Smrg: cgdmin ( cg fs -- 1st-data-block ) dup fs_dblkno l@ -rot cgstart + ; 1511.1Smrg: cgimin ( cg fs -- inode-block ) dup fs_iblkno l@ -rot cgstart + ; 1521.1Smrg: cgsblock ( cg fs -- super-block ) dup fs_sblkno l@ -rot cgstart + ; 1531.1Smrg: cgstod ( cg fs -- cg-block ) dup fs_cblkno l@ -rot cgstart + ; 1541.1Smrg 1551.1Smrg\ 1561.1Smrg\ Block and frag position macros 1571.1Smrg\ 1581.1Smrg 1591.1Smrg: blkoff ( pos fs -- off ) fs_qbmask x@ and ; 1601.1Smrg: fragoff ( pos fs -- off ) fs_qfmask x@ and ; 1611.1Smrg: lblktosize ( blk fs -- off ) fs_bshift l@ << ; 1621.1Smrg: lblkno ( pos fs -- off ) fs_bshift l@ >> ; 1631.1Smrg: numfrags ( pos fs -- off ) fs_fshift l@ >> ; 1641.1Smrg: blkroundup ( pos fs -- off ) dup fs_bmask l@ -rot fs_qbmask x@ + and ; 1651.1Smrg: fragroundup ( pos fs -- off ) dup fs_fmask l@ -rot fs_qfmask x@ + and ; 1661.1Smrg\ : fragroundup ( pos fs -- off ) tuck fs_qfmask x@ + swap fs_fmask l@ and ; 1671.1Smrg: fragstoblks ( pos fs -- off ) fs_fragshift l@ >> ; 1681.1Smrg: blkstofrags ( blk fs -- frag ) fs_fragshift l@ << ; 1691.1Smrg: fragnum ( fsb fs -- off ) fs_frag l@ 1- and ; 1701.1Smrg: blknum ( fsb fs -- off ) fs_frag l@ 1- not and ; 1711.1Smrg: dblksize ( lbn dino fs -- size ) 1721.1Smrg -rot ( fs lbn dino ) 1731.1Smrg di_size x@ ( fs lbn di_size ) 1741.1Smrg -rot dup 1+ ( di_size fs lbn lbn+1 ) 1751.1Smrg 2over fs_bshift l@ ( di_size fs lbn lbn+1 di_size b_shift ) 1761.1Smrg rot swap << >= ( di_size fs lbn res1 ) 1771.1Smrg swap ndaddr >= or if ( di_size fs ) 1781.1Smrg swap drop fs_bsize l@ exit ( size ) 1791.1Smrg then tuck blkoff swap fragroundup ( size ) 1801.1Smrg; 1811.1Smrg 1821.1Smrg 1831.1Smrg: ino-to-cg ( ino fs -- cg ) fs_ipg l@ / ; 1841.1Smrg: ino-to-fsbo ( ino fs -- fsb0 ) fs_inopb l@ mod ; 1851.1Smrg: ino-to-fsba ( ino fs -- ba ) \ Need to remove the stupid stack diags someday 1861.1Smrg 2dup ( ino fs ino fs ) 1871.1Smrg ino-to-cg ( ino fs cg ) 1881.1Smrg over ( ino fs cg fs ) 1891.1Smrg cgimin ( ino fs inode-blk ) 1901.1Smrg -rot ( inode-blk ino fs ) 1911.1Smrg tuck ( inode-blk fs ino fs ) 1921.1Smrg fs_ipg l@ ( inode-blk fs ino ipg ) 1931.1Smrg mod ( inode-blk fs mod ) 1941.1Smrg swap ( inode-blk mod fs ) 1951.1Smrg dup ( inode-blk mod fs fs ) 1961.1Smrg fs_inopb l@ ( inode-blk mod fs inopb ) 1971.1Smrg rot ( inode-blk fs inopb mod ) 1981.1Smrg swap ( inode-blk fs mod inopb ) 1991.1Smrg / ( inode-blk fs div ) 2001.1Smrg swap ( inode-blk div fs ) 2011.1Smrg blkstofrags ( inode-blk frag ) 2021.1Smrg + 2031.1Smrg; 2041.1Smrg: fsbtodb ( fsb fs -- db ) fs_fsbtodb l@ << ; 2051.1Smrg 2061.1Smrg\ 2071.1Smrg\ File stuff 2081.1Smrg\ 2091.1Smrg 2101.1Smrgniaddr /w* constant narraysize 2111.1Smrg 2121.1Smrgstruct 2131.1Smrg 8 field >f_ihandle \ device handle 2141.1Smrg 8 field >f_seekp \ seek pointer 2151.1Smrg 8 field >f_fs \ pointer to super block 2161.5She ufs1_dinode_SIZEOF field >f_di \ copy of on-disk inode 2171.1Smrg 8 field >f_buf \ buffer for data block 2181.1Smrg 4 field >f_buf_size \ size of data block 2191.1Smrg 4 field >f_buf_blkno \ block number of data block 2201.1Smrgconstant file_SIZEOF 2211.1Smrg 2221.1Smrgfile_SIZEOF buffer: the-file 2231.1Smrgsb-buf the-file >f_fs x! 2241.1Smrg 2251.5Sheufs1_dinode_SIZEOF buffer: cur-inode 2261.1Smrgh# 2000 buffer: indir-block 2271.1Smrg-1 value indir-addr 2281.1Smrg 2291.1Smrg\ 2301.1Smrg\ Translate a fileblock to a disk block 2311.1Smrg\ 2321.1Smrg\ We only allow single indirection 2331.1Smrg\ 2341.1Smrg 2351.1Smrg: block-map ( fileblock -- diskblock ) 2361.1Smrg \ Direct block? 2371.1Smrg dup ndaddr < if ( fileblock ) 2381.1Smrg cur-inode di_db ( arr-indx arr-start ) 2391.1Smrg swap la+ l@ exit ( diskblock ) 2401.1Smrg then ( fileblock ) 2411.1Smrg ndaddr - ( fileblock' ) 2421.1Smrg \ Now we need to check the indirect block 2431.1Smrg dup sb-buf fs_nindir l@ < if ( fileblock' ) 2441.1Smrg cur-inode di_ib l@ dup ( fileblock' indir-block indir-block ) 2451.1Smrg indir-addr <> if ( fileblock' indir-block ) 2461.1Smrg to indir-addr ( fileblock' ) 2471.1Smrg indir-block ( fileblock' indir-block ) 2481.1Smrg sb-buf dup fs_bsize l@ ( fileblock' indir-block fs fs_bsize ) 2491.1Smrg swap indir-addr swap ( fileblock' indir-block fs_bsize indiraddr fs ) 2501.1Smrg fsbtodb ( fileblock' indir-block fs_bsize db ) 2511.1Smrg strategy ( fileblock' nread ) 2521.1Smrg then ( fileblock' nread|indir-block ) 2531.1Smrg drop \ Really should check return value 2541.1Smrg indir-block swap la+ l@ exit 2551.1Smrg then 2561.1Smrg dup sb-buf fs_nindir - ( fileblock'' ) 2571.1Smrg \ Now try 2nd level indirect block -- just read twice 2581.1Smrg dup sb-buf fs_nindir l@ dup * < if ( fileblock'' ) 2591.1Smrg cur-inode di_ib 1 la+ l@ ( fileblock'' indir2-block ) 2601.1Smrg to indir-addr ( fileblock'' ) 2611.1Smrg \ load 1st level indir block 2621.1Smrg indir-block ( fileblock'' indir-block ) 2631.1Smrg sb-buf dup fs_bsize l@ ( fileblock'' indir-block fs fs_bsize ) 2641.1Smrg swap indir-addr swap ( fileblock'' indir-block fs_bsize indiraddr fs ) 2651.1Smrg fsbtodb ( fileblock'' indir-block fs_bsize db ) 2661.1Smrg strategy ( fileblock'' nread ) 2671.1Smrg drop ( fileblock'' ) 2681.1Smrg dup sb-buf fs_nindir / ( fileblock'' indir-offset ) 2691.1Smrg indir-block swap la+ l@ ( fileblock'' indirblock ) 2701.1Smrg to indir-addr ( fileblock'' ) 2711.1Smrg \ load 2nd level indir block 2721.1Smrg indir-block ( fileblock'' indir-block ) 2731.1Smrg sb-buf dup fs_bsize l@ ( fileblock'' indir-block fs fs_bsize ) 2741.1Smrg swap indir-addr swap ( fileblock'' indir-block fs_bsize indiraddr fs ) 2751.1Smrg fsbtodb ( fileblock'' indir-block fs_bsize db ) 2761.1Smrg strategy ( fileblock'' nread ) 2771.1Smrg drop ( fileblock'' ) 2781.1Smrg sb-buf fs_nindir l@ mod indir-block swap la+ l@ exit 2791.1Smrg then 2801.1Smrg ." block-map: exceeded max file size" cr 2811.1Smrg abort 2821.1Smrg; 2831.1Smrg 2841.1Smrg\ 2851.1Smrg\ Read file into internal buffer and return pointer and len 2861.1Smrg\ 2871.1Smrg 2881.4Seeh0 value cur-block \ allocated dynamically in ufs-open 2891.4Seeh0 value cur-blocksize \ size of cur-block 2901.1Smrg-1 value cur-blockno 2911.1Smrg0 value cur-offset 2921.1Smrg 2931.1Smrg: buf-read-file ( fs -- len buf ) 2941.1Smrg cur-offset swap ( seekp fs ) 2951.1Smrg 2dup blkoff ( seekp fs off ) 2961.1Smrg -rot 2dup lblkno ( off seekp fs block ) 2971.1Smrg swap 2dup cur-inode ( off seekp block fs block fs inop ) 2981.1Smrg swap dblksize ( off seekp block fs size ) 2991.1Smrg rot dup cur-blockno ( off seekp fs size block block cur ) 3001.1Smrg <> if ( off seekp fs size block ) 3011.1Smrg block-map ( off seekp fs size diskblock ) 3021.1Smrg dup 0= if ( off seekp fs size diskblock ) 3031.1Smrg over cur-block swap 0 fill ( off seekp fs size diskblock ) 3041.1Smrg boot-debug? if ." buf-read-file fell off end of file" cr then 3051.1Smrg else 3061.1Smrg 2dup sb-buf fsbtodb cur-block -rot strategy ( off seekp fs size diskblock nread ) 3071.1Smrg rot 2dup <> if " buf-read-file: short read." cr abort then 3081.1Smrg then ( off seekp fs diskblock nread size ) 3091.1Smrg nip nip ( off seekp fs size ) 3101.1Smrg else ( off seekp fs size block block cur ) 3111.1Smrg 2drop ( off seekp fs size ) 3121.1Smrg then 3131.1Smrg\ dup cur-offset + to cur-offset \ Set up next xfer -- not done 3141.1Smrg nip nip swap - ( len ) 3151.1Smrg cur-block 3161.1Smrg; 3171.1Smrg 3181.1Smrg\ 3191.1Smrg\ Read inode into cur-inode -- uses cur-block 3201.1Smrg\ 3211.1Smrg 3221.1Smrg: read-inode ( inode fs -- ) 3231.1Smrg twiddle ( inode fs -- inode fs ) 3241.1Smrg 3251.1Smrg cur-block ( inode fs -- inode fs buffer ) 3261.1Smrg 3271.1Smrg over ( inode fs buffer -- inode fs buffer fs ) 3281.1Smrg fs_bsize l@ ( inode fs buffer -- inode fs buffer size ) 3291.1Smrg 3301.1Smrg 2over ( inode fs buffer size -- inode fs buffer size inode fs ) 3311.1Smrg 2over ( inode fs buffer size inode fs -- inode fs buffer size inode fs buffer size ) 3321.1Smrg 2swap tuck ( inode fs buffer size inode fs buffer size -- inode fs buffer size buffer size fs inode fs ) 3331.1Smrg 3341.1Smrg ino-to-fsba ( inode fs buffer size buffer size fs inode fs -- inode fs buffer size buffer size fs fsba ) 3351.1Smrg swap ( inode fs buffer size buffer size fs fsba -- inode fs buffer size buffer size fsba fs ) 3361.1Smrg fsbtodb ( inode fs buffer size buffer size fsba fs -- inode fs buffer size buffer size db ) 3371.1Smrg 3381.1Smrg dup to cur-blockno ( inode fs buffer size buffer size dstart -- inode fs buffer size buffer size dstart ) 3391.1Smrg strategy ( inode fs buffer size buffer size dstart -- inode fs buffer size nread ) 3401.1Smrg <> if ." read-inode - residual" cr abort then 3411.1Smrg dup 2over ( inode fs buffer -- inode fs buffer buffer inode fs ) 3421.1Smrg ino-to-fsbo ( inode fs buffer -- inode fs buffer buffer fsbo ) 3431.5She ufs1_dinode_SIZEOF * + ( inode fs buffer buffer fsbo -- inode fs buffer dinop ) 3441.5She cur-inode ufs1_dinode_SIZEOF move ( inode fs buffer dinop -- inode fs buffer ) 3451.1Smrg \ clear out the old buffers 3461.1Smrg drop ( inode fs buffer -- inode fs ) 3471.1Smrg 2drop 3481.1Smrg; 3491.1Smrg 3501.1Smrg\ Identify inode type 3511.1Smrg 3521.5She: is-dir? ( ufs1_dinode -- true:false ) di_mode w@ ifmt and ifdir = ; 3531.5She: is-symlink? ( ufs1_dinode -- true:false ) di_mode w@ ifmt and iflnk = ; 3541.1Smrg 3551.1Smrg 3561.1Smrg 3571.1Smrg\ 3581.1Smrg\ Hunt for directory entry: 3591.1Smrg\ 3601.1Smrg\ repeat 3611.1Smrg\ load a buffer 3621.1Smrg\ while entries do 3631.1Smrg\ if entry == name return 3641.1Smrg\ next entry 3651.1Smrg\ until no buffers 3661.1Smrg\ 3671.1Smrg 3681.1Smrg: search-directory ( str len -- ino|0 ) 3691.1Smrg 0 to cur-offset 3701.1Smrg begin cur-offset cur-inode di_size x@ < while ( str len ) 3711.1Smrg sb-buf buf-read-file ( str len len buf ) 3721.1Smrg over 0= if ." search-directory: buf-read-file zero len" cr abort then 3731.1Smrg swap dup cur-offset + to cur-offset ( str len buf len ) 3741.1Smrg 2dup + nip ( str len buf bufend ) 3751.1Smrg swap 2swap rot ( bufend str len buf ) 3761.1Smrg begin dup 4 pick < while ( bufend str len buf ) 3771.1Smrg dup d_ino l@ 0<> if ( bufend str len buf ) 3781.1Smrg boot-debug? if dup dup d_name swap d_namlen c@ type cr then 3791.1Smrg 2dup d_namlen c@ = if ( bufend str len buf ) 3801.1Smrg dup d_name 2over ( bufend str len buf dname str len ) 3811.1Smrg comp 0= if ( bufend str len buf ) 3821.1Smrg \ Found it -- return inode 3831.1Smrg d_ino l@ nip nip nip ( dino ) 3841.1Smrg boot-debug? if ." Found it" cr then 3851.1Smrg exit ( dino ) 3861.1Smrg then 3871.1Smrg then ( bufend str len buf ) 3881.1Smrg then ( bufend str len buf ) 3891.1Smrg dup d_reclen w@ + ( bufend str len nextbuf ) 3901.1Smrg repeat 3911.1Smrg drop rot drop ( str len ) 3921.1Smrg repeat 3931.1Smrg 2drop 2drop 0 ( 0 ) 3941.1Smrg; 3951.1Smrg 3961.1Smrg: ffs_oldcompat ( -- ) 3971.1Smrg\ Make sure old ffs values in sb-buf are sane 3981.5She sb-buf fs_old_npsect dup l@ sb-buf fs_old_nsect l@ max swap l! 3991.5She sb-buf fs_old_interleave dup l@ 1 max swap l! 4001.5She sb-buf fs_old_postblformat l@ fs_42postblfmt = if 4011.5She 8 sb-buf fs_old_nrpos l! 4021.1Smrg then 4031.5She sb-buf fs_old_inodefmt l@ fs_44inodefmt < if 4041.1Smrg sb-buf fs_bsize l@ 4051.1Smrg dup ndaddr * 1- sb-buf fs_maxfilesize x! 4061.1Smrg niaddr 0 ?do 4071.1Smrg sb-buf fs_nindir l@ * dup ( sizebp sizebp -- ) 4081.1Smrg sb-buf fs_maxfilesize dup x@ ( sizebp sizebp *fs_maxfilesize fs_maxfilesize -- ) 4091.4Seeh rot ( sizebp *fs_maxfilesize fs_maxfilesize sizebp -- ) 4101.4Seeh + ( sizebp *fs_maxfilesize new_fs_maxfilesize -- ) 4111.4Seeh swap x! ( sizebp -- ) 4121.4Seeh loop drop ( -- ) 4131.1Smrg sb-buf dup fs_bmask l@ not swap fs_qbmask x! 4141.1Smrg sb-buf dup fs_fmask l@ not swap fs_qfmask x! 4151.1Smrg then 4161.1Smrg; 4171.1Smrg 4181.3Seeh: read-super ( sector -- ) 4191.3Seeh0 " seek" boot-ihandle $call-method 4201.1Smrg -1 = if 4211.1Smrg ." Seek failed" cr 4221.1Smrg abort 4231.1Smrg then 4241.1Smrg sb-buf sbsize " read" boot-ihandle $call-method 4251.1Smrg dup sbsize <> if 4261.1Smrg ." Read of superblock failed" cr 4271.1Smrg ." requested" space sbsize . 4281.1Smrg ." actual" space . cr 4291.1Smrg abort 4301.1Smrg else 4311.1Smrg drop 4321.1Smrg then 4331.3Seeh; 4341.3Seeh 4351.3Seeh: ufs-open ( bootpath,len -- ) 4361.3Seeh boot-ihandle -1 = if 4371.3Seeh over cif-open dup 0= if ( boot-path len ihandle? ) 4381.3Seeh ." Could not open device" space type cr 4391.3Seeh abort 4401.3Seeh then ( boot-path len ihandle ) 4411.3Seeh to boot-ihandle \ Save ihandle to boot device 4421.3Seeh then 2drop 4431.8Sjdc force-raid if 4441.8Sjdc boot-debug? if ." Force RAID superblock read" cr then 4451.6Smartin rf_protected dup to raid-offset 4461.3Seeh dev_bsize * sboff + read-super 4471.3Seeh sb-buf fs_magic l@ fs_magic_value <> if 4481.3Seeh ." Invalid superblock magic" cr 4491.3Seeh abort 4501.3Seeh then 4511.8Sjdc else 4521.8Sjdc boot-debug? if ." Normal superblock read" cr then 4531.8Sjdc sboff read-super 4541.8Sjdc sb-buf fs_magic l@ fs_magic_value <> if 4551.8Sjdc boot-debug? if ." RAID superblock read" cr then 4561.8Sjdc true to force-raid 4571.8Sjdc rf_protected dup to raid-offset 4581.8Sjdc dev_bsize * sboff + read-super 4591.8Sjdc sb-buf fs_magic l@ fs_magic_value <> if 4601.8Sjdc ." Invalid superblock magic" cr 4611.8Sjdc abort 4621.8Sjdc then 4631.8Sjdc then 4641.1Smrg then 4651.1Smrg sb-buf fs_bsize l@ dup maxbsize > if 4661.1Smrg ." Superblock bsize" space . ." too large" cr 4671.1Smrg abort 4681.1Smrg then 4691.4Seeh dup fs_SIZEOF < if 4701.1Smrg ." Superblock bsize < size of superblock" cr 4711.1Smrg abort 4721.1Smrg then 4731.4Seeh ffs_oldcompat ( fs_bsize -- fs_bsize ) 4741.4Seeh dup to cur-blocksize alloc-mem to cur-block \ Allocate cur-block 4751.1Smrg boot-debug? if ." ufs-open complete" cr then 4761.1Smrg; 4771.1Smrg 4781.1Smrg: ufs-close ( -- ) 4791.1Smrg boot-ihandle dup -1 <> if 4801.1Smrg cif-close -1 to boot-ihandle 4811.1Smrg then 4821.4Seeh cur-block 0<> if 4831.4Seeh cur-block cur-blocksize free-mem 4841.4Seeh then 4851.1Smrg; 4861.1Smrg 4871.1Smrg: boot-path ( -- boot-path ) 4881.1Smrg " bootpath" chosen-phandle get-package-property if 4891.1Smrg ." Could not find bootpath in /chosen" cr 4901.1Smrg abort 4911.1Smrg else 4921.1Smrg decode-string 2swap 2drop 4931.1Smrg then 4941.1Smrg; 4951.1Smrg 4961.1Smrg: boot-args ( -- boot-args ) 4971.1Smrg " bootargs" chosen-phandle get-package-property if 4981.1Smrg ." Could not find bootargs in /chosen" cr 4991.1Smrg abort 5001.1Smrg else 5011.1Smrg decode-string 2swap 2drop 5021.1Smrg then 5031.1Smrg; 5041.1Smrg 5051.1Smrg2000 buffer: boot-path-str 5061.1Smrg2000 buffer: boot-path-tmp 5071.1Smrg 5081.1Smrg: split-path ( path len -- right len left len ) 5091.1Smrg\ Split a string at the `/' 5101.1Smrg begin 5111.1Smrg dup -rot ( oldlen right len left ) 5121.1Smrg ascii / left-parse-string ( oldlen right len left len ) 5131.1Smrg dup 0<> if 4 roll drop exit then 5141.1Smrg 2drop ( oldlen right len ) 5151.1Smrg rot over = ( right len diff ) 5161.1Smrg until 5171.1Smrg; 5181.1Smrg 5191.1Smrg: find-file ( load-file len -- ) 5201.1Smrg rootino dup sb-buf read-inode ( load-file len -- load-file len ino ) 5211.1Smrg -rot ( load-file len ino -- pino load-file len ) 5221.1Smrg \ 5231.1Smrg \ For each path component 5241.1Smrg \ 5251.1Smrg begin split-path dup 0<> while ( pino right len left len -- ) 5261.8Sjdc cur-inode is-dir? not if ." Inode not directory" cr false exit then 5271.1Smrg boot-debug? if ." Looking for" space 2dup type space ." in directory..." cr then 5281.1Smrg search-directory ( pino right len left len -- pino right len ino|false ) 5291.1Smrg dup 0= if ." Bad path" cr abort then ( pino right len cino ) 5301.1Smrg sb-buf read-inode ( pino right len ) 5311.1Smrg cur-inode is-symlink? if \ Symlink -- follow the damn thing 5321.1Smrg \ Save path in boot-path-tmp 5331.1Smrg boot-path-tmp strmov ( pino new-right len ) 5341.1Smrg 5351.1Smrg \ Now deal with symlink 5361.1Smrg cur-inode di_size x@ ( pino right len linklen ) 5371.1Smrg dup sb-buf fs_maxsymlinklen l@ ( pino right len linklen linklen maxlinklen ) 5381.1Smrg < if \ Now join the link to the path 5391.5She cur-inode di_db l@ ( pino right len linklen linkp ) 5401.1Smrg swap boot-path-str strmov ( pino right len new-linkp linklen ) 5411.1Smrg else \ Read file for symlink -- Ugh 5421.1Smrg \ Read link into boot-path-str 5431.1Smrg boot-path-str dup sb-buf fs_bsize l@ 5441.1Smrg 0 block-map ( pino right len linklen boot-path-str bsize blockno ) 5451.1Smrg strategy drop swap ( pino right len boot-path-str linklen ) 5461.1Smrg then ( pino right len linkp linklen ) 5471.1Smrg \ Concatenate the two paths 5481.1Smrg strcat ( pino new-right newlen ) 5491.1Smrg swap dup c@ ascii / = if \ go to root inode? 5501.1Smrg rot drop rootino -rot ( rino len right ) 5511.1Smrg then 5521.1Smrg rot dup sb-buf read-inode ( len right pino ) 5531.1Smrg -rot swap ( pino right len ) 5541.1Smrg then ( pino right len ) 5551.1Smrg repeat 5561.1Smrg 2drop drop 5571.8Sjdc true 5581.1Smrg; 5591.1Smrg 5601.1Smrg: read-file ( size addr -- ) 5611.1Smrg \ Read x bytes from a file to buffer 5621.1Smrg begin over 0> while 5631.1Smrg cur-offset cur-inode di_size x@ > if ." read-file EOF exceeded" cr abort then 5641.1Smrg sb-buf buf-read-file ( size addr len buf ) 5651.1Smrg over 2over drop swap ( size addr len buf addr len ) 5661.1Smrg move ( size addr len ) 5671.1Smrg dup cur-offset + to cur-offset ( size len newaddr ) 5681.1Smrg tuck + ( size len newaddr ) 5691.1Smrg -rot - swap ( newaddr newsize ) 5701.1Smrg repeat 5711.1Smrg 2drop 5721.1Smrg; 5731.1Smrg 5741.4Seeh\ 5751.4Seeh\ According to the 1275 addendum for SPARC processors: 5761.4Seeh\ Default load-base is 0x4000. At least 0x8.0000 or 5771.4Seeh\ 512KB must be available at that address. 5781.4Seeh\ 5791.4Seeh\ The Fcode bootblock can take up up to 8KB (O.K., 7.5KB) 5801.4Seeh\ so load programs at 0x4000 + 0x2000=> 0x6000 5811.4Seeh\ 5821.4Seeh 5831.4Seehh# 6000 constant loader-base 5841.1Smrg 5851.1Smrg\ 5861.1Smrg\ Elf support -- find the load addr 5871.1Smrg\ 5881.1Smrg 5891.1Smrg: is-elf? ( hdr -- res? ) h# 7f454c46 = ; 5901.1Smrg 5911.1Smrg\ 5921.1Smrg\ Finally we finish it all off 5931.1Smrg\ 5941.1Smrg 5951.1Smrg: load-file-signon ( load-file len boot-path len -- load-file len boot-path len ) 5961.1Smrg ." Loading file" space 2over type cr ." from device" space 2dup type cr 5971.1Smrg; 5981.1Smrg 5991.1Smrg: load-file-print-size ( size -- size ) 6001.1Smrg ." Loading" space dup . space ." bytes of file..." cr 6011.1Smrg; 6021.1Smrg 6031.1Smrg: load-file ( load-file len boot-path len -- load-base ) 6041.1Smrg boot-debug? if load-file-signon then 6051.1Smrg the-file file_SIZEOF 0 fill \ Clear out file structure 6061.8Sjdc \ copy "load-file len boot-path len" in case we need to set "force-raid" 6071.8Sjdc 2over 2over ( load-file len boot-path len load-file len boot-path len ) 6081.8Sjdc ufs-open ( load-file len boot-path len load-file len ) 6091.8Sjdc find-file not if ( load-file len boot-path len ) 6101.8Sjdc force-raid not if 6111.8Sjdc true to force-raid ( ) 6121.8Sjdc ufs-close 6131.8Sjdc 2drop 2drop drop ( load-file len boot-path len ) 6141.8Sjdc ufs-open ( load-file len ) 6151.8Sjdc find-file ( true:false ) 6161.8Sjdc drop 6171.8Sjdc else 6181.8Sjdc abort 6191.8Sjdc then 6201.8Sjdc else 6211.8Sjdc \ We didn't set "force-raid", discard the copies 6221.8Sjdc 2drop 2drop ( ) 6231.8Sjdc then 6241.1Smrg 6251.1Smrg \ 6261.1Smrg \ Now we've found the file we should read it in in one big hunk 6271.1Smrg \ 6281.1Smrg 6291.1Smrg cur-inode di_size x@ ( file-len ) 6301.1Smrg dup " to file-size" evaluate ( file-len ) 6311.1Smrg boot-debug? if load-file-print-size then 6321.1Smrg 0 to cur-offset 6331.1Smrg loader-base ( buf-len addr ) 6341.1Smrg 2dup read-file ( buf-len addr ) 6351.1Smrg ufs-close ( buf-len addr ) 6361.1Smrg dup is-elf? if ." load-file: not an elf executable" cr abort then 6371.1Smrg 6381.1Smrg \ Luckily the prom should be able to handle ELF executables by itself 6391.1Smrg 6401.1Smrg nip ( addr ) 6411.1Smrg; 6421.1Smrg 6431.1Smrg: do-boot ( bootfile -- ) 6441.1Smrg ." NetBSD IEEE 1275 Bootblock" cr 6451.1Smrg boot-path load-file ( -- load-base ) 6461.1Smrg dup 0<> if " to load-base init-program" evaluate then 6471.1Smrg; 6481.1Smrg 6491.1Smrg 6501.1Smrgboot-args ascii V strchr 0<> swap drop if 6511.1Smrg true to boot-debug? 6521.1Smrgthen 6531.1Smrg 6541.1Smrgboot-args ascii D strchr 0= swap drop if 6551.1Smrg " /ofwboot" do-boot 6561.1Smrgthen exit 6571.1Smrg 6581.1Smrg 659