bootblk.fth revision 1.16
11.16Sandvar\	$NetBSD: bootblk.fth,v 1.16 2021/07/24 21:31:36 andvar 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.10Seeh\	Copyright (c) 1998-2010 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\
201.1Smrg\	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
211.1Smrg\	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
221.1Smrg\	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
231.1Smrg\	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
241.1Smrg\	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
251.1Smrg\	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
261.1Smrg\	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
271.1Smrg\	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
281.1Smrg\	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
291.1Smrg\	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
301.1Smrg\
311.1Smrg
321.1Smrgoffset16
331.1Smrghex
341.1Smrgheaders
351.1Smrg
361.1Smrgfalse value boot-debug?
371.1Smrg
381.11Seeh: KB d# 1024 * ;
391.11Seeh
401.1Smrg\
411.1Smrg\ First some housekeeping:  Open /chosen and set up vectors into
421.1Smrg\	client-services
431.1Smrg
441.1Smrg" /chosen" find-package 0=  if ." Cannot find /chosen" 0 then
451.1Smrgconstant chosen-phandle
461.1Smrg
471.1Smrg" /openprom/client-services" find-package 0=  if 
481.1Smrg	." Cannot find client-services" cr abort
491.1Smrgthen constant cif-phandle
501.1Smrg
511.1Smrgdefer cif-claim ( align size virt -- base )
521.1Smrgdefer cif-release ( size virt -- )
531.1Smrgdefer cif-open ( cstr -- ihandle|0 )
541.1Smrgdefer cif-close ( ihandle -- )
551.1Smrgdefer cif-read ( len adr ihandle -- #read )
561.1Smrgdefer cif-seek ( low high ihandle -- -1|0|1 )
571.1Smrg\ defer cif-peer ( phandle -- phandle )
581.1Smrg\ defer cif-getprop ( len adr cstr phandle -- )
591.1Smrg
601.10Seeh: find-cif-method ( method len -- xf )
611.1Smrg   cif-phandle find-method drop 
621.1Smrg;
631.1Smrg
641.10Seeh" claim" find-cif-method  to  cif-claim
651.10Seeh" open" find-cif-method  to  cif-open
661.10Seeh" close" find-cif-method  to  cif-close
671.10Seeh" read" find-cif-method  to  cif-read
681.10Seeh" seek" find-cif-method  to  cif-seek
691.1Smrg
701.1Smrg: twiddle ( -- ) ." ." ; \ Need to do this right.  Just spit out periods for now.
711.1Smrg
721.1Smrg\
731.1Smrg\ Support routines
741.1Smrg\
751.1Smrg
761.10Seeh\ 64-bit math support
771.10Seeh
781.10Seehhere h# ffff over l! <w@ constant little-endian?
791.10Seeh: ul>d ( l -- d.lo d.hi )	0 ;
801.10Seeh: l>d ( l -- d.lo d.hi )	dup 0<  if  -1  else  0  then ;
811.10Seeh: d>l ( d.lo d.hi -- l )	drop ;
821.10Seeh: d@ ( addr -- d.lo d.hi )	dup l@ swap la1+ l@ little-endian? invert  if  swap  then ;
831.10Seeh: d! ( d.lo d.hi addr -- )
841.10Seeh   little-endian? invert  if  -rot swap rot  then  tuck la1+ l! l! ;
851.10Seeh: d-and ( d1 d2 -- d1-and-d2 )  rot and -rot and swap ;
861.10Seeh: d*u ( d1 u -- d2 )		tuck um* drop -rot um* rot + ;
871.10Seeh: d<< ( d1 n -- d1<<n )	\ Hope this works
881.12Seeh   ?dup  if  \ Shifting by 0 doesn't appear to work properly.
891.12Seeh      tuck <<			( d.lo n d.hi' )
901.12Seeh      -rot 2dup <<		( d.hi' d.lo n d.lo' )
911.12Seeh      -rot d# 32 swap - >>	( d.hi' d.lo' lo.hi )
921.12Seeh      rot +
931.12Seeh   then
941.10Seeh;
951.10Seeh: d>> ( d1 n -- d1>>n )	\ Hope this works
961.12Seeh   ?dup  if  \ Shifting by 0 doesn't appear to work properly.
971.12Seeh      rot over >>	-rot	( d.lo' d.hi n )
981.12Seeh      2dup >> -rot		( d.lo' d.hi' d.hi n )
991.12Seeh      d# 32 swap - << rot + swap
1001.12Seeh   then
1011.10Seeh;
1021.10Seeh: d> ( d1 d2 -- d1>d2? )
1031.10Seeh   rot swap 2dup = if
1041.10Seeh      2drop > exit
1051.10Seeh   then
1061.10Seeh   > nip nip
1071.10Seeh;
1081.10Seeh: d>= ( d1 d2 -- d1>=d2? )
1091.10Seeh   rot swap 2dup =  if
1101.10Seeh      2drop >= exit
1111.10Seeh   then
1121.10Seeh   >= nip nip
1131.10Seeh;
1141.10Seeh: d< ( d1 d2 -- d1<d2? )	d>= invert ;
1151.10Seeh: d= ( d1 d2 -- d1=d2? )	rot = -rot = and ;
1161.10Seeh: d<> ( d1 d2 -- d1<>d2? )	d= invert ;
1171.10Seeh
1181.10Seeh
1191.10Seeh\ String support 
1201.10Seeh
1211.1Smrg: strcmp ( s1 l1 s2 l2 -- true:false )
1221.10Seeh   rot tuck <>  if  3drop false exit  then
1231.1Smrg   comp 0=
1241.1Smrg;
1251.1Smrg
1261.1Smrg\ Move string into buffer
1271.1Smrg
1281.1Smrg: strmov ( s1 l1 d -- d l1 )
1291.1Smrg   dup 2over swap -rot		( s1 l1 d s1 d l1 )
1301.1Smrg   move				( s1 l1 d )
1311.1Smrg   rot drop swap
1321.1Smrg;
1331.1Smrg
1341.1Smrg\ Move s1 on the end of s2 and return the result
1351.1Smrg
1361.1Smrg: strcat ( s1 l1 s2 l2 -- d tot )
1371.1Smrg   2over swap 				( s1 l1 s2 l2 l1 s1 )
1381.1Smrg   2over + rot				( s1 l1 s2 l2 s1 d l1 )
1391.1Smrg   move rot + 				( s1 s2 len )
1401.1Smrg   rot drop				( s2 len )
1411.1Smrg;
1421.1Smrg
1431.1Smrg: strchr ( s1 l1 c -- s2 l2 )
1441.1Smrg   begin
1451.1Smrg      dup 2over 0= if			( s1 l1 c c s1  )
1461.1Smrg         2drop drop exit then
1471.1Smrg      c@ = if				( s1 l1 c )
1481.1Smrg         drop exit then
1491.1Smrg      -rot /c - swap ca1+		( c l2 s2 )
1501.1Smrg     swap rot
1511.1Smrg  again
1521.1Smrg;
1531.1Smrg
1541.1Smrg   
1551.1Smrg: cstr ( ptr -- str len )
1561.1Smrg   dup 
1571.1Smrg   begin dup c@ 0<>  while + repeat
1581.1Smrg   over -
1591.1Smrg;
1601.1Smrg
1611.1Smrg\
1621.10Seeh\ BSD UFS parameters
1631.1Smrg\
1641.1Smrg
1651.10Seehfload	ffs.fth.h
1661.10Seehfload   lfs.fth.h
1671.1Smrg
1681.1Smrgsbsize buffer: sb-buf
1691.1Smrg-1 value boot-ihandle
1701.1Smrgdev_bsize value bsize
1711.3Seeh0 value raid-offset	\ Offset if it's a raid-frame partition
1721.1Smrg
1731.10Seeh: strategy ( addr size db.lo db.hi -- nread )
1741.10Seeh    raid-offset l>d d+			( addr size db.lo' db.hi' )
1751.10Seeh    bsize d*u				( addr size sector.lo sector.hi )
1761.10Seeh    " seek" boot-ihandle $call-method -1 = if 
1771.10Seeh	." strategy: Seek failed" cr
1781.10Seeh	abort
1791.10Seeh    then				( addr size )
1801.10Seeh    " read" boot-ihandle $call-method
1811.10Seeh;
1821.10Seeh
1831.10Seeh
1841.10Seeh\
1851.10Seeh\ Multi-FS support
1861.10Seeh\
1871.10Seeh\ XXX Maybe the different filesystems should be segregated into separate files
1881.10Seeh\ XXX that are individually fload-ed.
1891.10Seeh\
1901.10Seeh
1911.10Seehdefer fs-size
1921.10Seehdefer di-size
1931.10Seehdefer di-mode
1941.10Seehdefer /dino
1951.10Seehdefer cgstart
1961.10Seehdefer di-db@
1971.10Seehdefer di-ib@
1981.10Seehdefer ib-ib@
1991.10Seehdefer fs-bsize
2001.10Seehdefer fsbtodb
2011.10Seehdefer blksize
2021.10Seehdefer lblkno
2031.10Seehdefer blkoff
2041.10Seehdefer read-inode
2051.10Seeh\ LFS ifile
2061.10Seehdefer /ifile
2071.10Seehdefer if_daddr
2081.10Seeh
2091.10Seeh\
2101.10Seeh\ FFS Cylinder group macros
2111.10Seeh\
2121.10Seeh
2131.10Seeh: cgdmin ( cg fs -- d-1st-data-block )	dup fs_dblkno l@ l>d 2swap cgstart d+ ;
2141.10Seeh: cgimin ( cg fs -- d-inode-block )	dup fs_iblkno l@ l>d 2swap cgstart d+ ;
2151.10Seeh: cgsblock ( cg fs -- d-super-block )	dup fs_sblkno l@ l>d 2swap cgstart d+ ;
2161.10Seeh: cgstod ( cg fs -- d-cg-block )	dup fs_cblkno l@ l>d 2swap cgstart d+ ;
2171.10Seeh
2181.10Seeh\
2191.10Seeh\ FFS Block and frag position macros
2201.10Seeh\
2211.10Seeh
2221.10Seeh: ffs-blkoff ( pos.lo pos.hi fs -- off.lo off.hi )	fs_qbmask d@ d-and ;
2231.10Seeh\ : ffs-fragoff ( pos.lo pos.hi fs -- off.lo off.hi )	fs_qfmask d@ d-and ;
2241.10Seeh\ : ffs-lblktosize ( blk fs -- off.lo off.hi )		0 fs_bshift l@ d<< ;
2251.10Seeh: ffs-lblkno ( pos.lo pos.hi fs -- off.lo off.hi )	fs_bshift l@ d>> ;
2261.10Seeh: ffs-numfrags ( pos.lo pos.hi fs -- off.lo off.hi )	fs_fshift l@ d>> ;
2271.10Seeh: ffs-blkroundup ( pos.lo pos.hi fs -- off.lo off.hi )
2281.10Seeh    >r r@ fs_qbmask d@ d+ r> fs_bmask l@ l>d d-and
2291.10Seeh;
2301.10Seeh: ffs-fragroundup ( pos.lo pos.hi fs -- off.lo off.hi )
2311.10Seeh    >r r@ fs_qfmask d@ d+ r> fs_fmask l@ l>d d-and
2321.10Seeh;
2331.10Seeh: ffs-fragstoblks ( pos.lo pos.hi fs -- off.lo off.hi )	fs_fragshift l@ d>> ;
2341.10Seeh: ffs-blkstofrags ( blk fs -- frag )			fs_fragshift l@ << ;
2351.10Seeh\ : ffs-fragnum ( fsb fs -- off )			fs_frag l@ 1- and ;
2361.10Seeh\ : ffs-blknum ( fsb fs -- off )			fs_frag l@ 1- not and ;
2371.10Seeh: ffs-dblksize ( lbn.lo lbn.hi inodep fs -- size )
2381.10Seeh   >r -rot 2dup ndaddr l>d d>		( inop d-lbn >ndaddr? )
2391.10Seeh   -rot 1 0 d+				( inop >ndaddr? d-lbn+1 )
2401.10Seeh   r@ fs_bshift l@ d<<			( inop >ndaddr? d-lbn+1<<bshift )
2411.10Seeh   2swap >r di-size d@			( d-lbn+1<<bshift d-size )
2421.10Seeh   2swap 2over d< r> or  if		( d-size )
2431.10Seeh	2drop r> fs-bsize l@ exit
2441.10Seeh    then
2451.10Seeh    r@ ffs-blkoff			( size.lo size.hi )
2461.10Seeh    r> ffs-fragroundup d>l		( size )
2471.10Seeh;
2481.10Seeh
2491.10Seeh: ino-to-cg ( ino fs -- cg )		fs_ipg l@ / ;
2501.10Seeh: ino-to-fsbo ( ino fs -- fsb0 )	fs_inopb l@ mod ;
2511.10Seeh: ino-to-fsba ( ino fs -- ba.lo ba.hi )	\ Need to remove the stupid stack diags someday
2521.10Seeh   2dup 				( ino fs ino fs )
2531.10Seeh   ino-to-cg				( ino fs cg )
2541.10Seeh   over					( ino fs cg fs )
2551.10Seeh   cgimin				( ino fs inode-blk.lo inode-blk.hi )
2561.10Seeh   2swap				( d-inode-blk ino fs )
2571.10Seeh   tuck 				( d-inode-blk fs ino fs )
2581.10Seeh   fs_ipg l@ 				( d-inode-blk fs ino ipg )
2591.10Seeh   mod					( d-inode-blk fs mod )
2601.10Seeh   swap					( d-inode-blk mod fs )
2611.10Seeh   dup 					( d-inode-blk mod fs fs )
2621.10Seeh   fs_inopb l@ 				( d-inode-blk mod fs inopb )
2631.10Seeh   rot 					( d-inode-blk fs inopb mod )
2641.10Seeh   swap					( d-inode-blk fs mod inopb )
2651.10Seeh   /					( d-inode-blk fs div )
2661.10Seeh   swap					( d-inode-blk div fs )
2671.10Seeh   ffs-blkstofrags			( d-inode-blk frag )
2681.10Seeh   0 d+
2691.10Seeh;
2701.10Seeh: ffs-fsbtodb ( fsb.lo fsb.hi fs -- db.lo db.hi )
2711.10Seeh    fs_fsbtodb l@ d<<
2721.10Seeh;
2731.10Seeh
2741.10Seeh
2751.10Seeh\
2761.10Seeh\ LFS suff
2771.10Seeh\
2781.10Seeh: lfs-blkoff ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_bmask d@ d-and ;
2791.10Seeh\ : lfs-fragoff ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_ffmask d@ d-and ;
2801.10Seeh\ : lfs-lblktosize ( blk fs -- off.lo off.hi )		0 lfs_bshift l@ d<< ;
2811.10Seeh: lfs-lblkno ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_bshift l@ d>> ;
2821.10Seeh: lfs-numfrags ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_ffshift l@ d>> ;
2831.10Seeh: lfs-roundup ( pos.lo pos.hi mask.lo mask.hi )
2841.10Seeh   2swap 2over d+ 2swap			( d-pos* d-mask )
2851.10Seeh   invert swap invert swap d-and
2861.10Seeh;
2871.10Seeh: lfs-blkroundup ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_bmask d@ lfs-roundup ;
2881.10Seeh: lfs-fragroundup ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_ffmask d@ lfs-roundup ;
2891.10Seeh: lfs-fragstoblks ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_fbshift l@ d>> ;
2901.10Seeh: lfs-dblksize ( lbn.lo lbn.hi inodep fs -- size )
2911.10Seeh   >r -rot 2dup ndaddr l>d d>		( inop d-lbn >ndaddr? )
2921.10Seeh   -rot 1 0 d+				( inop >ndaddr? d-lbn+1 )
2931.10Seeh   r@ fs_bshift l@ d<<			( inop >ndaddr? d-lbn+1<<bshift )
2941.10Seeh   2swap >r di-size d@			( d-lbn+1<<bshift d-size )
2951.10Seeh   2swap 2over d< r> or  if		( d-size )
2961.10Seeh      2drop r> fs-bsize l@ exit
2971.1Smrg   then
2981.10Seeh   r@ lfs-blkoff			( size.lo size.hi )
2991.10Seeh   r> lfs-fragroundup d>l		( size )
3001.10Seeh;
3011.10Seeh: lfs-fsbtodb ( fsb.lo fsb.hi fs -- db.lo db.hi )
3021.10Seeh    lfs_fsbtodb l@ d<<
3031.1Smrg;
3041.1Smrg
3051.10Seeh\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
3061.1Smrg\
3071.10Seeh\ The rest of the multi-filesystem stuff
3081.1Smrg\
3091.10Seeh\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
3101.1Smrg
3111.10Seeh\
3121.10Seeh\ FFS v1
3131.10Seeh\
3141.10Seeh: di-db-v1@ ( indx dinode -- db.lo db.hi )	di1_db swap la+ l@ l>d ;
3151.10Seeh: di-ib-v1@ ( indx dinode -- db.lo db.hi )	di1_ib swap la+ l@ l>d ;
3161.10Seeh: ib-ib-v1@ ( indx iblk -- db.lo db.hi )	swap la+ l@ l>d ;
3171.10Seeh
3181.10Seeh: cgbase ( cg fs -- daddr.lo daddr.hi ) fs_fpg l@ um* ;
3191.10Seeh: cgstart-ufs1 ( cg fs -- cgstart ) 
3201.10Seeh    2dup fs_old_cgmask l@ invert and		( cg fs stuff )
3211.10Seeh    over fs_old_cgoffset l@ um*			( cg fs off.lo off.hi )
3221.10Seeh    2swap cgbase d+				( off.lo off.hi )
3231.1Smrg;
3241.1Smrg
3251.1Smrg\
3261.10Seeh\ FFS v2
3271.1Smrg\
3281.1Smrg
3291.10Seeh: di-db-v2@ ( indx dinode -- db.lo db.hi )	di2_db swap 2* la+ d@ ;
3301.10Seeh: di-ib-v2@ ( indx dinode -- db.lo db.hi )	di2_ib swap 2* la+ d@ ;
3311.10Seeh: ib-ib-v2@ ( indx iblk -- db.lo db.hi )	2* la+ d@ ;
3321.1Smrg
3331.10Seeh\
3341.10Seeh\ LFS v1
3351.10Seeh\
3361.1Smrg
3371.1Smrg
3381.1Smrg\
3391.1Smrg\ File stuff
3401.1Smrg\
3411.1Smrg
3421.1Smrgniaddr /w* constant narraysize
3431.1Smrg
3441.16Sandvar\ Assume UFS2 dinodes are always bigger than UFS1
3451.10Seehufs2_dinode_SIZEOF buffer: cur-inode
3461.13Seeh0 value indir-block
3471.10Seehcreate indir-addr -1 , -1 ,
3481.1Smrg
3491.1Smrg\
3501.1Smrg\ Translate a fileblock to a disk block
3511.1Smrg\
3521.10Seeh\ We don't do triple indirect blocks.
3531.1Smrg\
3541.1Smrg
3551.10Seeh\ Get the disk address from a single indirect block
3561.10Seeh: ib@ ( indx indir.lo indir.hi -- db.lo db.hi )
3571.10Seeh    2dup indir-addr d@ d<>  if		( indx indir.hi indir.lo )
3581.10Seeh	indir-addr d!			( indx )
3591.10Seeh	indir-block 			( indx indir-block )
3601.10Seeh	sb-buf fs-bsize l@		( indx indir-block fs fs-bsize )
3611.10Seeh	indir-addr d@ sb-buf		( indx indir-block fs-bsize indiraddr fs )
3621.10Seeh	fsbtodb 			( indx indir-block fs-bsize db.lo db.hi )
3631.10Seeh	strategy 0			( indx nread 0 ) \ Really should check return value
3641.10Seeh    then
3651.10Seeh    2drop				( indx )
3661.10Seeh    indir-block ib-ib@
3671.10Seeh;
3681.10Seeh
3691.10Seeh
3701.10Seeh: block-map ( fileblock -- diskblock.lo diskblock.hi )
3711.10Seeh    \ Direct block?
3721.10Seeh    dup ndaddr <  if			( fileblock )
3731.10Seeh	cur-inode di-db@ exit		( diskblock.lo diskblock.hi )
3741.10Seeh    then 				( fileblock )
3751.10Seeh    ndaddr -				( fileblock' )
3761.10Seeh    \ Now we need to check the indirect block
3771.10Seeh    dup sb-buf fs_nindir l@ <  if	( fileblock' )
3781.10Seeh	0 cur-inode di-ib@		( fileblock' indir.lo indir.hi )
3791.10Seeh	ib@ exit			( db.lo db.hi )
3801.1Smrg   then
3811.1Smrg   dup sb-buf fs_nindir -		( fileblock'' )
3821.1Smrg   \ Now try 2nd level indirect block -- just read twice 
3831.10Seeh   dup sb-buf fs_nindir l@ dup * >= if	( fileblock'' )
3841.10Seeh       ." block-map: exceeded max file size" cr
3851.10Seeh       abort
3861.1Smrg   then
3871.10Seeh       
3881.10Seeh   1 cur-inode di-ib@		( fileblock'' ib.lo ib.hi )
3891.10Seeh   
3901.10Seeh   \ Get 1st indirect block and find the 2nd indirect block
3911.10Seeh   rot dup sb-buf fs_nindir u/mod	( ib2.lo ib2.hi indx2 indx1 )
3921.10Seeh   2swap ib@			( indx2 ib2.lo ib2.hi )
3931.10Seeh   
3941.10Seeh   \ Get 2nd indirect block and find our diskblock
3951.10Seeh   ib@				( db.lo db.hi )
3961.1Smrg;
3971.1Smrg
3981.1Smrg\
3991.1Smrg\ Read file into internal buffer and return pointer and len
4001.1Smrg\
4011.1Smrg
4021.4Seeh0 value cur-block			\ allocated dynamically in ufs-open
4031.10Seeh0 value cur-blocksize			\ size allocated  to  cur-block
4041.10Seehcreate cur-blockno -1 l, -1 l,		\ Current disk block.
4051.10Seeh-1 value file-blockno			\ Current file block no.
4061.10Seeh0 value file-offset			\ Current file offset, max 4GB.
4071.10Seeh
4081.10Seeh: buf-read-file ( fs -- buf len )
4091.10Seeh    >r file-offset			( seek )
4101.10Seeh    dup l>d r@ lblkno drop		( seek blk )
4111.10Seeh    dup l>d cur-inode r@ blksize	( seek blk blksize )
4121.10Seeh    over file-blockno <> if		( seek blk blksize )
4131.10Seeh	over  to  file-blockno
4141.10Seeh	swap block-map			( seek blksize fsblk.lo fsblk.hi )
4151.10Seeh	2dup or 0=  if			( seek blksize fsblk.lo fsblk.hi )
4161.10Seeh	    \ Clear out curblock  XXX Why? Idunno.
4171.10Seeh	    2drop dup
4181.10Seeh	    cur-block swap erase	( seek blksize )
4191.10Seeh	    boot-debug?  if ." buf-read-file reading block 0" cr then
4201.10Seeh	    -1 l>d			\ Invalid disk block
4211.10Seeh	else
4221.10Seeh	    \ Call strategy to load the correct block.
4231.10Seeh	    r@ fsbtodb			( seek blksize dblk.lo dblk.hi )
4241.10Seeh	    rot >r cur-block r@ 2over	( seek addr size db.lo db.hi )
4251.10Seeh	    strategy r@	<>  if  ." buf-read-file: short read." cr abort  then
4261.10Seeh	    r> -rot			( seek size db.lo db.hi )
4271.10Seeh	then
4281.10Seeh	\ Save the new current disk block number
4291.10Seeh	cur-blockno d!			( seek size )
4301.10Seeh   else					
4311.10Seeh      nip				( seek size )
4321.10Seeh   then
4331.10Seeh   \ Now figure out how much we have in the buffer.
4341.10Seeh   swap l>d r> blkoff			( size off.lo off.hi )
4351.10Seeh   d>l cur-block over +			( size off buf )
4361.10Seeh   -rot -				( buf siz )
4371.1Smrg;
4381.1Smrg
4391.1Smrg\
4401.1Smrg\ Read inode into cur-inode -- uses cur-block
4411.1Smrg\ 
4421.1Smrg
4431.10Seeh: read-inode-ffs ( inode fs -- )
4441.10Seeh    twiddle
4451.10Seeh
4461.10Seeh    >r dup r@ ino-to-fsba		( ino fsblk.lo fsblck.hi )
4471.10Seeh    r@ fsbtodb				( ino dblk.lo dblk.hi )
4481.10Seeh    2dup cur-blockno d@ d<>  if		( ino dblk.lo dblk.hi )
4491.10Seeh	\ We need  to  read the block
4501.10Seeh	cur-block r@ fs-bsize l@	( ino dblk.lo dblk.hi addr size )
4511.10Seeh	>r r@ 2over strategy r> <> if	( ino dblk.lo dblk.hi )
4521.10Seeh	    ." read-inode - residual" cr abort
4531.10Seeh	then
4541.10Seeh	2dup cur-blockno d!		( ino dblk.lo dblk.hi )
4551.10Seeh    then 2drop				( ino )
4561.1Smrg
4571.10Seeh    r> ino-to-fsbo /dino *		( off )
4581.10Seeh    cur-block + cur-inode /dino move	( )
4591.10Seeh;
4601.10Seeh
4611.10Seeh: find-inode-sector ( ino fs -- d-dblkno true | false )
4621.10Seeh   >r r@ lfs_ifile l@ r@  read-inode	( ino )
4631.10Seeh
4641.10Seeh   r@ lfs_ifpb l@ u/mod			( rem q )
4651.10Seeh
4661.10Seeh   r@ lfs_cleansz l@ +
4671.10Seeh   r@ lfs_segtabsz l@ +			( rem blkno )
4681.1Smrg
4691.10Seeh   r@ fs-bsize l@ um* rot /ifile um* d+	( dseekp )
4701.1Smrg
4711.10Seeh   drop  to  file-offset r@ buf-read-file	( buf len )
4721.10Seeh
4731.10Seeh   /ifile <  if  r> 2drop false exit  then	( buf )
4741.10Seeh
4751.10Seeh   if_daddr l@ l>d r> fsbtodb		( daddr )
4761.10Seeh   2dup lfs_unused_daddr l>d d=  if  2drop false  then
4771.10Seeh   true
4781.10Seeh;
4791.10Seeh
4801.10Seeh: read-inode-lfs ( inode fs -- )
4811.10Seeh   twiddle
4821.10Seeh
4831.10Seeh   >r dup r@ lfs_ifile l@ =  if		( ino  r: fs )
4841.10Seeh      r@ lfs_idaddr l@ l>d		( ino d-idaddr )
4851.10Seeh      r@ fsbtodb			( ino d-db )
4861.10Seeh   else
4871.10Seeh      dup r@ find-inode-sector 0= abort" Could not find inode sector!"
4881.10Seeh   then					( ino d-db )
4891.10Seeh   
4901.10Seeh    2dup cur-blockno d@ d<>  if		( ino dblk.lo dblk.hi )
4911.10Seeh	\ We need to read the block
4921.10Seeh	cur-block r@ fs-bsize l@	( ino dblk.lo dblk.hi addr size )
4931.10Seeh	>r r@ 2over strategy r> <> if	( ino dblk.lo dblk.hi )
4941.10Seeh	    ." read-inode - residual" cr abort
4951.10Seeh	then
4961.10Seeh	2dup cur-blockno d!		( ino dblk.lo dblk.hi )
4971.10Seeh    then  2drop				( ino )
4981.10Seeh
4991.10Seeh    r@ lfs_inopb l@			( ino cnt )
5001.10Seeh    swap cur-block  begin		( cnt ino p )
5011.10Seeh       tuck di_inumber l@ over <>	( cnt p ino !found? )
5021.10Seeh    while				( cnt p ino )
5031.10Seeh	  rot 1- ?dup 0=  abort" Could not find inode!"
5041.10Seeh	  rot /dino + swap -rot		( cnt ino p )
5051.10Seeh    repeat  swap			( cnt ino p )
5061.10Seeh
5071.10Seeh    cur-inode /dino move		( cnt ino )
5081.10Seeh	  
5091.10Seeh    r> 3drop
5101.1Smrg;
5111.1Smrg
5121.1Smrg\ Identify inode type
5131.1Smrg
5141.10Seeh: is-dir? ( ufs1_dinode -- is-dir? )		di-mode w@ ifmt and ifdir = ;
5151.10Seeh: is-symlink? ( ufs1_dinode -- is-symlink? )	di-mode w@ ifmt and iflnk = ;
5161.10Seeh
5171.10Seeh\
5181.10Seeh\ Multi-FS initialiation.
5191.10Seeh\
5201.10Seeh\ It's way down here so all the fs-specific routines have already been defined.
5211.10Seeh\
5221.10Seeh
5231.10Seeh: init-ffs-common ( -- )
5241.10Seeh   ' fs_SIZEOF  to  fs-size 
5251.10Seeh   ' fs_bsize  to  fs-bsize
5261.10Seeh   ' ffs-dblksize  to  blksize
5271.10Seeh   ' read-inode-ffs  to  read-inode
5281.10Seeh   ' ffs-fsbtodb  to  fsbtodb
5291.10Seeh   ' ffs-lblkno  to  lblkno
5301.10Seeh   ' ffs-blkoff  to   blkoff
5311.10Seeh;   
5321.10Seeh
5331.10Seeh
5341.10Seeh: ffs-oldcompat ( -- )
5351.10Seeh   \ Make sure old ffs values in sb-buf are sane
5361.10Seeh   sb-buf fs_old_npsect dup l@ sb-buf fs_old_nsect l@ max swap l!
5371.10Seeh   sb-buf fs_old_interleave dup l@ 1 max swap l!
5381.10Seeh   sb-buf fs_old_postblformat l@ fs_42postblfmt =  if
5391.10Seeh      8 sb-buf fs_old_nrpos l!
5401.10Seeh   then
5411.10Seeh   sb-buf fs_old_inodefmt l@ fs_44inodefmt <  if
5421.10Seeh      sb-buf fs-bsize l@ 
5431.10Seeh      dup ndaddr um* 1 d- sb-buf fs_maxfilesize d!
5441.10Seeh      niaddr 0  ?do
5451.10Seeh	 sb-buf fs_nindir l@ * dup	( sizebp sizebp )
5461.10Seeh	 sb-buf fs_maxfilesize dup d@ ( sizebp sizebp *mxfs mxfs.lo mxfs.hi )
5471.10Seeh	 2over drop l>d d+ 2swap d!	( sizebp )
5481.10Seeh      loop  drop 			( )
5491.10Seeh      sb-buf dup fs_bmask l@ invert l>d rot fs_qbmask d!
5501.10Seeh      sb-buf dup fs_fmask l@ invert l>d rot fs_qfmask d!
5511.10Seeh   then
5521.10Seeh;
5531.10Seeh
5541.10Seeh
5551.10Seeh: init-ffs-v1 ( -- )
5561.12Seeh   boot-debug?  if  ." FFS v1" cr  then
5571.10Seeh   init-ffs-common
5581.10Seeh   ' di1_size  to  di-size
5591.10Seeh   ' di1_mode  to  di-mode
5601.10Seeh   ' ufs1_dinode_SIZEOF  to  /dino
5611.10Seeh   ' cgstart-ufs1  to  cgstart
5621.10Seeh   ' di-db-v1@  to  di-db@
5631.10Seeh   ' di-ib-v1@  to  di-ib@
5641.10Seeh   ' ib-ib-v1@  to  ib-ib@
5651.10Seeh   ffs-oldcompat
5661.10Seeh;
5671.10Seeh
5681.10Seeh: init-ffs-v2 ( -- )
5691.12Seeh   boot-debug?  if  ." FFS v2" cr  then
5701.10Seeh   init-ffs-common
5711.10Seeh   ' di2_size  to  di-size
5721.10Seeh   ' di2_mode  to  di-mode
5731.10Seeh   ' ufs2_dinode_SIZEOF  to  /dino
5741.10Seeh   ' cgbase  to  cgstart
5751.10Seeh   ' di-db-v2@  to  di-db@
5761.10Seeh   ' di-ib-v2@  to  di-ib@
5771.10Seeh   ' ib-ib-v2@  to  ib-ib@
5781.10Seeh;
5791.10Seeh
5801.10Seeh: init-lfs-common ( -- )
5811.10Seeh   ' dlfs_SIZEOF  to  fs-size 
5821.10Seeh   ' di1_size  to  di-size
5831.10Seeh   ' di1_mode  to  di-mode
5841.15Sdholland   ' lfs32_dinode_SIZEOF  to  /dino
5851.10Seeh   ' cgbase  to  cgstart
5861.10Seeh   ' di-db-v1@  to  di-db@
5871.10Seeh   ' di-ib-v1@  to  di-ib@
5881.10Seeh   ' ib-ib-v1@  to  ib-ib@
5891.10Seeh   ' lfs-dblksize  to  blksize
5901.10Seeh   ' read-inode-lfs  to  read-inode
5911.10Seeh   ' lfs-fsbtodb  to  fsbtodb
5921.10Seeh   ' lfs-lblkno  to  lblkno
5931.10Seeh   ' lfs-blkoff  to  blkoff
5941.10Seeh;
5951.10Seeh
5961.10Seeh: init-lfs-v1 ( -- )
5971.12Seeh   boot-debug?  if  ." LFS v1" cr  then
5981.10Seeh   init-lfs-common
5991.10Seeh   ' lfs_ibsize  to  fs-bsize
6001.10Seeh   ' ifile_v1_SIZEOF  to  /ifile
6011.10Seeh   ' if1_daddr  to  if_daddr
6021.10Seeh;   
6031.10Seeh
6041.10Seeh: init-lfs-v2 ( -- )
6051.12Seeh   boot-debug?  if  ." LFS v2" cr  then
6061.10Seeh   init-lfs-common
6071.10Seeh   ' lfs_bsize  to  fs-bsize
6081.14Sjdc   ' ifile32_SIZEOF  to  /ifile
6091.10Seeh   ' if2_daddr  to  if_daddr
6101.10Seeh;   
6111.10Seeh
6121.10Seeh
6131.10Seeh: fs-magic? ( sb -- is-ufs? )
6141.10Seeh   \ The LFS magic is the first word in the superblock
6151.10Seeh   dup lfs_magic l@ lfs_magic_value =  if
6161.10Seeh      dup lfs_version l@  case		( sb sel )
6171.10Seeh	 1  of  init-lfs-v1 drop true exit  endof
6181.10Seeh	 2  of  init-lfs-v2 drop true exit  endof
6191.10Seeh	 ." Invalid LFS version."  \ Try FFS.
6201.10Seeh      endcase
6211.10Seeh   then					( sb )
6221.10Seeh   \ The FFS magic is at the end of the superblock
6231.11Seeh   \ XXX we should check to make sure this is not an alternate SB.
6241.10Seeh   fs_magic l@  case
6251.10Seeh      fs1_magic_value  of  init-ffs-v1 true  endof
6261.10Seeh      fs2_magic_value  of  init-ffs-v2 true  endof
6271.10Seeh      false swap	\ Return false
6281.10Seeh   endcase
6291.10Seeh;
6301.1Smrg
6311.1Smrg
6321.1Smrg
6331.1Smrg\
6341.1Smrg\ Hunt for directory entry:
6351.1Smrg\ 
6361.1Smrg\ repeat
6371.1Smrg\    load a buffer
6381.1Smrg\    while entries do
6391.1Smrg\       if entry == name return
6401.1Smrg\       next entry
6411.1Smrg\ until no buffers
6421.1Smrg\
6431.1Smrg
6441.10Seeh: search-dir-block ( str len buf len -- ino | 0 )
6451.10Seeh    2dup + nip				( str len buf bufend )
6461.10Seeh    swap 2swap rot			( bufend str len direct )
6471.10Seeh    begin  dup 4 pick <  while		( bufend str len direct )
6481.10Seeh	    dup d_ino l@ 0<>  if	( bufend str len direct )
6491.10Seeh		boot-debug?  if
6501.10Seeh		    \ Print the current file name
6511.10Seeh		    dup dup d_name swap d_namlen c@ type cr
6521.10Seeh		then
6531.10Seeh		2dup d_namlen c@ =  if	( bufend str len direct )
6541.10Seeh		    dup d_name 2over	( bufend str len direct dname str len )
6551.10Seeh		    comp 0= if		( bufend str len direct )
6561.10Seeh			\ Found it -- return inode
6571.10Seeh			d_ino l@ nip nip nip	( dino )
6581.10Seeh			boot-debug?  if  ." Found it" cr  then 
6591.10Seeh			exit 		( dino )
6601.10Seeh		    then
6611.10Seeh		then			( bufend str len direct )
6621.10Seeh	    then			( bufend str len direct )
6631.10Seeh	    dup d_reclen w@ +		( bufend str len nextdirect )
6641.10Seeh    repeat
6651.10Seeh    2drop 2drop 0
6661.10Seeh;
6671.10Seeh    
6681.10Seeh
6691.10Seeh: search-directory ( str len -- ino | 0 )
6701.10Seeh    0  to  file-offset
6711.10Seeh    begin
6721.10Seeh	file-offset cur-inode di-size d@ drop <
6731.10Seeh    while				( str len )
6741.10Seeh	    \ Read a directory block
6751.10Seeh	    sb-buf buf-read-file	( str len buf len )
6761.10Seeh	    dup 0=  if  ." search-directory: buf-read-file zero len" cr abort  then
6771.10Seeh	    dup file-offset +  to  file-offset	( str len buf len )
6781.10Seeh
6791.10Seeh	    2over 2swap search-dir-block ?dup  if
6801.10Seeh		\ Found it
6811.10Seeh		nip nip exit
6821.10Seeh	    then			( str len )
6831.10Seeh    repeat
6841.10Seeh    2drop 2drop 0			( 0 )
6851.1Smrg;
6861.1Smrg
6871.3Seeh: read-super ( sector -- )
6881.10Seeh   0 " seek" boot-ihandle $call-method -1 =  if 
6891.10Seeh      ." Seek failed" cr abort
6901.1Smrg   then
6911.1Smrg   sb-buf sbsize " read" boot-ihandle $call-method
6921.1Smrg   dup sbsize <>  if
6931.1Smrg      ." Read of superblock failed" cr
6941.1Smrg      ." requested" space sbsize .
6951.1Smrg      ." actual" space . cr
6961.1Smrg      abort
6971.1Smrg   else 
6981.1Smrg      drop
6991.1Smrg   then
7001.3Seeh;
7011.3Seeh
7021.11Seeh: check-supers ( -- found? )
7031.11Seeh   \ Superblocks used to be 8KB into the partition, but ffsv2 changed that.
7041.11Seeh   \ See comments in src/sys/ufs/ffs/fs.h
7051.11Seeh   \ Put a list of offets to check on the stack, ending with -1
7061.11Seeh   -1
7071.11Seeh   0
7081.11Seeh   d# 128 KB
7091.11Seeh   d# 64 KB
7101.11Seeh   8 KB
7111.11Seeh   
7121.11Seeh   begin  dup -1 <>  while			( -1 .. off )
7131.11Seeh	 raid-offset dev_bsize * + read-super	( -1 .. )
7141.11Seeh	 sb-buf fs-magic?  if			( -1 .. )
7151.11Seeh	    begin  -1 =  until	 \ Clean out extra stuff from stack
7161.11Seeh	    true exit
7171.11Seeh	 then
7181.11Seeh   repeat
7191.11Seeh   drop false
7201.11Seeh;
7211.11Seeh
7221.10Seeh: ufs-open ( bootpath len -- )
7231.3Seeh   boot-ihandle -1 =  if
7241.10Seeh      2dup + 0 swap c!	\ Nul terminate.
7251.10Seeh      over cif-open dup 0=  if 	( boot-path len ihandle? )
7261.10Seeh	 ." Could not open device" space type cr 
7271.10Seeh	 abort
7281.3Seeh      then 				( boot-path len ihandle )
7291.10Seeh      to  boot-ihandle			\ Save ihandle to boot device
7301.10Seeh   then
7311.10Seeh   2drop
7321.10Seeh   
7331.10Seeh   boot-debug?  if ." Try a RAID superblock read" cr  then
7341.11Seeh   \ RAIDFRAME skips 64 sectors.
7351.11Seeh   d# 64  to  raid-offset
7361.11Seeh   check-supers invert  if
7371.10Seeh      boot-debug?  if ." Try a normal superblock read" cr  then
7381.10Seeh      0  to  raid-offset 
7391.11Seeh      check-supers 0=  abort" Invalid superblock magic"
7401.1Smrg   then
7411.10Seeh   sb-buf fs-bsize l@ dup maxbsize >  if
7421.1Smrg      ." Superblock bsize" space . ." too large" cr
7431.1Smrg      abort
7441.1Smrg   then 
7451.10Seeh   dup fs-size <  if
7461.1Smrg      ." Superblock bsize < size of superblock" cr
7471.1Smrg      abort
7481.1Smrg   then
7491.10Seeh   dup  to  cur-blocksize alloc-mem  to  cur-block    \ Allocate cur-block
7501.13Seeh   cur-blocksize alloc-mem  to  indir-block
7511.10Seeh   boot-debug?  if  ." ufs-open complete" cr  then
7521.1Smrg;
7531.1Smrg
7541.1Smrg: ufs-close ( -- ) 
7551.10Seeh    boot-ihandle dup -1 <>  if
7561.10Seeh	cif-close -1  to  boot-ihandle 
7571.10Seeh    then
7581.10Seeh    cur-block 0<> if
7591.13Seeh       cur-block cur-blocksize free-mem
7601.13Seeh       indir-block cur-blocksize free-mem
7611.10Seeh    then
7621.1Smrg;
7631.1Smrg
7641.1Smrg: boot-path ( -- boot-path )
7651.10Seeh    " bootpath" chosen-phandle get-package-property  if
7661.10Seeh	." Could not find bootpath in /chosen" cr
7671.10Seeh	abort
7681.10Seeh    else
7691.10Seeh	decode-string 2swap 2drop
7701.10Seeh    then
7711.1Smrg;
7721.1Smrg
7731.1Smrg: boot-args ( -- boot-args )
7741.10Seeh    " bootargs" chosen-phandle get-package-property  if
7751.10Seeh	." Could not find bootargs in /chosen" cr
7761.10Seeh	abort
7771.10Seeh    else
7781.10Seeh	decode-string 2swap 2drop
7791.10Seeh    then
7801.1Smrg;
7811.1Smrg
7821.1Smrg2000 buffer: boot-path-str
7831.1Smrg2000 buffer: boot-path-tmp
7841.1Smrg
7851.1Smrg: split-path ( path len -- right len left len )
7861.1Smrg\ Split a string at the `/'
7871.10Seeh    begin
7881.10Seeh	dup -rot				( oldlen right len left )
7891.10Seeh	ascii / left-parse-string		( oldlen right len left len )
7901.10Seeh	dup 0<>  if  4 roll drop exit  then
7911.10Seeh	2drop					( oldlen right len )
7921.10Seeh	rot over =				( right len diff )
7931.10Seeh    until
7941.1Smrg;
7951.1Smrg
7961.1Smrg: find-file ( load-file len -- )
7971.10Seeh    rootino dup sb-buf read-inode	( load-file len pino )
7981.10Seeh    -rot				( pino load-file len )
7991.10Seeh    \
8001.10Seeh    \ For each path component
8011.10Seeh    \ 
8021.10Seeh    begin  split-path dup 0<>  while	( pino right len left len )
8031.10Seeh	    cur-inode is-dir? not  if  ." Inode not directory" cr abort  then
8041.10Seeh	    boot-debug?  if  ." Looking for" space 2dup type space ." in directory..." cr  then
8051.10Seeh	    search-directory		( pino right len ino|false )
8061.10Seeh	    dup 0=  abort" Bad path" 	( pino right len cino )
8071.10Seeh	    sb-buf read-inode			( pino right len )
8081.10Seeh	    cur-inode is-symlink?  if		\ Symlink -- follow the damn thing
8091.10Seeh		\ Save path in boot-path-tmp
8101.10Seeh		boot-path-tmp strmov		( pino new-right len )
8111.10Seeh		
8121.10Seeh		\ Now deal with symlink  XXX drop high word of linklen
8131.10Seeh		cur-inode di-size d@ drop	( pino right len linklen.lo )
8141.10Seeh		dup sb-buf fs_maxsymlinklen l@	( pino right len linklen linklen maxlinklen )
8151.10Seeh		<  if				\ Now join the link to the path
8161.10Seeh		    0 cur-inode di-db@ drop	( pino right len linklen linkp )
8171.10Seeh		    swap boot-path-str strmov	( pino right len new-linkp linklen )
8181.10Seeh		else				\ Read file for symlink -- Ugh
8191.10Seeh		    \ Read link into boot-path-str
8201.10Seeh		    boot-path-str dup sb-buf fs-bsize l@
8211.10Seeh		    0 block-map			( pino right len linklen boot-path-str bsize blockno.lo blockno.hi )
8221.10Seeh		    strategy drop swap		( pino right len boot-path-str linklen )
8231.10Seeh		then 				( pino right len linkp linklen )
8241.10Seeh		\ Concatenate the two paths
8251.10Seeh		strcat				( pino new-right newlen )
8261.10Seeh		swap dup c@ ascii / =  if	\ go to root inode?
8271.10Seeh		    rot drop rootino -rot	( rino len right )
8281.10Seeh		then
8291.10Seeh		rot dup sb-buf read-inode	( len right pino )
8301.10Seeh		-rot swap			( pino right len )
8311.10Seeh	    then				( pino right len )
8321.10Seeh    repeat
8331.10Seeh    2drop drop
8341.10Seeh;
8351.10Seeh
8361.10Seeh: .read-file-msg ( addr xxx siz -- addr xxx siz )
8371.10Seeh    boot-debug? if
8381.10Seeh	." Copying " dup . ." bytes to " 3 pick . cr
8391.10Seeh    then
8401.10Seeh;
8411.10Seeh       
8421.10Seeh: read-file ( addr size -- )
8431.10Seeh    noop \ In case we need to debug this
8441.10Seeh    \ Read x bytes from a file to buffer
8451.10Seeh    begin  dup 0>  while
8461.10Seeh	    file-offset cur-inode di-size d@ drop >  if
8471.10Seeh		." read-file EOF exceeded" cr abort
8481.10Seeh	    then
8491.10Seeh	    sb-buf buf-read-file		( addr size buf len )
8501.10Seeh	    
8511.10Seeh	    .read-file-msg
8521.10Seeh	    
8531.10Seeh	    \ Copy len bytes to addr  XXX min ( len, size ) ?
8541.10Seeh	    2over drop 3dup swap move drop	( addr size buf len )
8551.10Seeh	    
8561.10Seeh	    dup file-offset +  to  file-offset	( addr size buf len )
8571.10Seeh	    
8581.10Seeh	    nip tuck - -rot + swap		( addr' size' )
8591.10Seeh    repeat
8601.10Seeh    2drop
8611.1Smrg;
8621.1Smrg
8631.10Seeh" load-base " evaluate constant loader-base
8641.1Smrg
8651.1Smrg: load-file-signon ( load-file len boot-path len -- load-file len boot-path len )
8661.1Smrg   ." Loading file" space 2over type cr ." from device" space 2dup type cr
8671.1Smrg;
8681.1Smrg
8691.1Smrg: load-file ( load-file len boot-path len -- load-base )
8701.10Seeh   boot-debug?  if  load-file-signon  then
8711.10Seeh   
8721.10Seeh   ufs-open 				( load-file len )
8731.10Seeh   find-file				( )
8741.1Smrg
8751.10Seeh    \
8761.10Seeh    \ Now we've found the file we should read it in in one big hunk
8771.10Seeh    \
8781.10Seeh    
8791.10Seeh    cur-inode di-size d@  if  ." File len >2GB!" cr abort  then
8801.10Seeh\    dup " to file-size " evaluate	( file-len ) \ Wassthis?
8811.10Seeh    boot-debug?  if
8821.10Seeh	." Loading " dup . ."  bytes of file..." cr
8831.10Seeh    then
8841.10Seeh    0  to  file-offset
8851.10Seeh    -1  to  file-blockno
8861.10Seeh    loader-base				( buf-len addr )
8871.10Seeh    tuck swap read-file			( addr )
8881.10Seeh    ufs-close				( addr )
8891.1Smrg;
8901.1Smrg
8911.1Smrg: do-boot ( bootfile -- )
8921.11Seeh   ." NetBSD IEEE 1275 Multi-FS Bootblock" cr
8931.16Sandvar   ." Version $NetBSD: bootblk.fth,v 1.16 2021/07/24 21:31:36 andvar Exp $" cr
8941.11Seeh   boot-path load-file ( -- load-base )
8951.11Seeh   dup 0<>  if  " init-program " evaluate  then
8961.10Seeh; 
8971.1Smrg
8981.1Smrg
8991.10Seehboot-args ascii V strchr 0<> swap drop  if
9001.10Seeh    true  to  boot-debug?
9011.1Smrgthen
9021.1Smrg
9031.10Seehboot-args ascii D strchr 0= swap drop  if
9041.10Seeh    " /ofwboot" do-boot
9051.10Seehthen  exit
9061.1Smrg
9071.1Smrg
908