bootblk.fth revision 1.11
11.11Seeh\	$NetBSD: bootblk.fth,v 1.11 2010/02/17 15:49:19 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.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.10Seeh   tuck <<			( d.lo n d.hi' )
891.10Seeh   -rot 2dup <<			( d.hi' d.lo n d.lo' )
901.10Seeh   -rot d# 32 swap - >>		( d.hi' d.lo' lo.hi )
911.10Seeh   rot +
921.10Seeh;
931.10Seeh: d>> ( d1 n -- d1>>n )	\ Hope this works
941.10Seeh   rot over >>	-rot		( d.lo' d.hi n )
951.10Seeh   2dup >> -rot			( d.lo' d.hi' d.hi n )
961.10Seeh   d# 32 swap - << rot + swap
971.10Seeh;
981.10Seeh: d> ( d1 d2 -- d1>d2? )
991.10Seeh   rot swap 2dup = if
1001.10Seeh      2drop > exit
1011.10Seeh   then
1021.10Seeh   > nip nip
1031.10Seeh;
1041.10Seeh: d>= ( d1 d2 -- d1>=d2? )
1051.10Seeh   rot swap 2dup =  if
1061.10Seeh      2drop >= exit
1071.10Seeh   then
1081.10Seeh   >= nip nip
1091.10Seeh;
1101.10Seeh: d< ( d1 d2 -- d1<d2? )	d>= invert ;
1111.10Seeh: d= ( d1 d2 -- d1=d2? )	rot = -rot = and ;
1121.10Seeh: d<> ( d1 d2 -- d1<>d2? )	d= invert ;
1131.10Seeh
1141.10Seeh
1151.10Seeh\ String support 
1161.10Seeh
1171.1Smrg: strcmp ( s1 l1 s2 l2 -- true:false )
1181.10Seeh   rot tuck <>  if  3drop false exit  then
1191.1Smrg   comp 0=
1201.1Smrg;
1211.1Smrg
1221.1Smrg\ Move string into buffer
1231.1Smrg
1241.1Smrg: strmov ( s1 l1 d -- d l1 )
1251.1Smrg   dup 2over swap -rot		( s1 l1 d s1 d l1 )
1261.1Smrg   move				( s1 l1 d )
1271.1Smrg   rot drop swap
1281.1Smrg;
1291.1Smrg
1301.1Smrg\ Move s1 on the end of s2 and return the result
1311.1Smrg
1321.1Smrg: strcat ( s1 l1 s2 l2 -- d tot )
1331.1Smrg   2over swap 				( s1 l1 s2 l2 l1 s1 )
1341.1Smrg   2over + rot				( s1 l1 s2 l2 s1 d l1 )
1351.1Smrg   move rot + 				( s1 s2 len )
1361.1Smrg   rot drop				( s2 len )
1371.1Smrg;
1381.1Smrg
1391.1Smrg: strchr ( s1 l1 c -- s2 l2 )
1401.1Smrg   begin
1411.1Smrg      dup 2over 0= if			( s1 l1 c c s1  )
1421.1Smrg         2drop drop exit then
1431.1Smrg      c@ = if				( s1 l1 c )
1441.1Smrg         drop exit then
1451.1Smrg      -rot /c - swap ca1+		( c l2 s2 )
1461.1Smrg     swap rot
1471.1Smrg  again
1481.1Smrg;
1491.1Smrg
1501.1Smrg   
1511.1Smrg: cstr ( ptr -- str len )
1521.1Smrg   dup 
1531.1Smrg   begin dup c@ 0<>  while + repeat
1541.1Smrg   over -
1551.1Smrg;
1561.1Smrg
1571.1Smrg\
1581.10Seeh\ BSD UFS parameters
1591.1Smrg\
1601.1Smrg
1611.10Seehfload	ffs.fth.h
1621.10Seehfload   lfs.fth.h
1631.1Smrg
1641.1Smrgsbsize buffer: sb-buf
1651.1Smrg-1 value boot-ihandle
1661.1Smrgdev_bsize value bsize
1671.3Seeh0 value raid-offset	\ Offset if it's a raid-frame partition
1681.1Smrg
1691.10Seeh: strategy ( addr size db.lo db.hi -- nread )
1701.10Seeh    raid-offset l>d d+			( addr size db.lo' db.hi' )
1711.10Seeh    bsize d*u				( addr size sector.lo sector.hi )
1721.10Seeh    " seek" boot-ihandle $call-method -1 = if 
1731.10Seeh	." strategy: Seek failed" cr
1741.10Seeh	abort
1751.10Seeh    then				( addr size )
1761.10Seeh    " read" boot-ihandle $call-method
1771.10Seeh;
1781.10Seeh
1791.10Seeh
1801.10Seeh\
1811.10Seeh\ Multi-FS support
1821.10Seeh\
1831.10Seeh\ XXX Maybe the different filesystems should be segregated into separate files
1841.10Seeh\ XXX that are individually fload-ed.
1851.10Seeh\
1861.10Seeh
1871.10Seehdefer fs-size
1881.10Seehdefer di-size
1891.10Seehdefer di-mode
1901.10Seehdefer /dino
1911.10Seehdefer cgstart
1921.10Seehdefer di-db@
1931.10Seehdefer di-ib@
1941.10Seehdefer ib-ib@
1951.10Seehdefer fs-bsize
1961.10Seehdefer fsbtodb
1971.10Seehdefer blksize
1981.10Seehdefer lblkno
1991.10Seehdefer blkoff
2001.10Seehdefer read-inode
2011.10Seeh\ LFS ifile
2021.10Seehdefer /ifile
2031.10Seehdefer if_daddr
2041.10Seeh
2051.10Seeh\
2061.10Seeh\ FFS Cylinder group macros
2071.10Seeh\
2081.10Seeh
2091.10Seeh: cgdmin ( cg fs -- d-1st-data-block )	dup fs_dblkno l@ l>d 2swap cgstart d+ ;
2101.10Seeh: cgimin ( cg fs -- d-inode-block )	dup fs_iblkno l@ l>d 2swap cgstart d+ ;
2111.10Seeh: cgsblock ( cg fs -- d-super-block )	dup fs_sblkno l@ l>d 2swap cgstart d+ ;
2121.10Seeh: cgstod ( cg fs -- d-cg-block )	dup fs_cblkno l@ l>d 2swap cgstart d+ ;
2131.10Seeh
2141.10Seeh\
2151.10Seeh\ FFS Block and frag position macros
2161.10Seeh\
2171.10Seeh
2181.10Seeh: ffs-blkoff ( pos.lo pos.hi fs -- off.lo off.hi )	fs_qbmask d@ d-and ;
2191.10Seeh\ : ffs-fragoff ( pos.lo pos.hi fs -- off.lo off.hi )	fs_qfmask d@ d-and ;
2201.10Seeh\ : ffs-lblktosize ( blk fs -- off.lo off.hi )		0 fs_bshift l@ d<< ;
2211.10Seeh: ffs-lblkno ( pos.lo pos.hi fs -- off.lo off.hi )	fs_bshift l@ d>> ;
2221.10Seeh: ffs-numfrags ( pos.lo pos.hi fs -- off.lo off.hi )	fs_fshift l@ d>> ;
2231.10Seeh: ffs-blkroundup ( pos.lo pos.hi fs -- off.lo off.hi )
2241.10Seeh    >r r@ fs_qbmask d@ d+ r> fs_bmask l@ l>d d-and
2251.10Seeh;
2261.10Seeh: ffs-fragroundup ( pos.lo pos.hi fs -- off.lo off.hi )
2271.10Seeh    >r r@ fs_qfmask d@ d+ r> fs_fmask l@ l>d d-and
2281.10Seeh;
2291.10Seeh: ffs-fragstoblks ( pos.lo pos.hi fs -- off.lo off.hi )	fs_fragshift l@ d>> ;
2301.10Seeh: ffs-blkstofrags ( blk fs -- frag )			fs_fragshift l@ << ;
2311.10Seeh\ : ffs-fragnum ( fsb fs -- off )			fs_frag l@ 1- and ;
2321.10Seeh\ : ffs-blknum ( fsb fs -- off )			fs_frag l@ 1- not and ;
2331.10Seeh: ffs-dblksize ( lbn.lo lbn.hi inodep fs -- size )
2341.10Seeh   >r -rot 2dup ndaddr l>d d>		( inop d-lbn >ndaddr? )
2351.10Seeh   -rot 1 0 d+				( inop >ndaddr? d-lbn+1 )
2361.10Seeh   r@ fs_bshift l@ d<<			( inop >ndaddr? d-lbn+1<<bshift )
2371.10Seeh   2swap >r di-size d@			( d-lbn+1<<bshift d-size )
2381.10Seeh   2swap 2over d< r> or  if		( d-size )
2391.10Seeh	2drop r> fs-bsize l@ exit
2401.10Seeh    then
2411.10Seeh    r@ ffs-blkoff			( size.lo size.hi )
2421.10Seeh    r> ffs-fragroundup d>l		( size )
2431.10Seeh;
2441.10Seeh
2451.10Seeh: ino-to-cg ( ino fs -- cg )		fs_ipg l@ / ;
2461.10Seeh: ino-to-fsbo ( ino fs -- fsb0 )	fs_inopb l@ mod ;
2471.10Seeh: ino-to-fsba ( ino fs -- ba.lo ba.hi )	\ Need to remove the stupid stack diags someday
2481.10Seeh   2dup 				( ino fs ino fs )
2491.10Seeh   ino-to-cg				( ino fs cg )
2501.10Seeh   over					( ino fs cg fs )
2511.10Seeh   cgimin				( ino fs inode-blk.lo inode-blk.hi )
2521.10Seeh   2swap				( d-inode-blk ino fs )
2531.10Seeh   tuck 				( d-inode-blk fs ino fs )
2541.10Seeh   fs_ipg l@ 				( d-inode-blk fs ino ipg )
2551.10Seeh   mod					( d-inode-blk fs mod )
2561.10Seeh   swap					( d-inode-blk mod fs )
2571.10Seeh   dup 					( d-inode-blk mod fs fs )
2581.10Seeh   fs_inopb l@ 				( d-inode-blk mod fs inopb )
2591.10Seeh   rot 					( d-inode-blk fs inopb mod )
2601.10Seeh   swap					( d-inode-blk fs mod inopb )
2611.10Seeh   /					( d-inode-blk fs div )
2621.10Seeh   swap					( d-inode-blk div fs )
2631.10Seeh   ffs-blkstofrags			( d-inode-blk frag )
2641.10Seeh   0 d+
2651.10Seeh;
2661.10Seeh: ffs-fsbtodb ( fsb.lo fsb.hi fs -- db.lo db.hi )
2671.10Seeh    fs_fsbtodb l@ d<<
2681.10Seeh;
2691.10Seeh
2701.10Seeh
2711.10Seeh\
2721.10Seeh\ LFS suff
2731.10Seeh\
2741.10Seeh: lfs-blkoff ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_bmask d@ d-and ;
2751.10Seeh\ : lfs-fragoff ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_ffmask d@ d-and ;
2761.10Seeh\ : lfs-lblktosize ( blk fs -- off.lo off.hi )		0 lfs_bshift l@ d<< ;
2771.10Seeh: lfs-lblkno ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_bshift l@ d>> ;
2781.10Seeh: lfs-numfrags ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_ffshift l@ d>> ;
2791.10Seeh: lfs-roundup ( pos.lo pos.hi mask.lo mask.hi )
2801.10Seeh   2swap 2over d+ 2swap			( d-pos* d-mask )
2811.10Seeh   invert swap invert swap d-and
2821.10Seeh;
2831.10Seeh: lfs-blkroundup ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_bmask d@ lfs-roundup ;
2841.10Seeh: lfs-fragroundup ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_ffmask d@ lfs-roundup ;
2851.10Seeh: lfs-fragstoblks ( pos.lo pos.hi fs -- off.lo off.hi )	lfs_fbshift l@ d>> ;
2861.10Seeh: lfs-dblksize ( lbn.lo lbn.hi inodep fs -- size )
2871.10Seeh   >r -rot 2dup ndaddr l>d d>		( inop d-lbn >ndaddr? )
2881.10Seeh   -rot 1 0 d+				( inop >ndaddr? d-lbn+1 )
2891.10Seeh   r@ fs_bshift l@ d<<			( inop >ndaddr? d-lbn+1<<bshift )
2901.10Seeh   2swap >r di-size d@			( d-lbn+1<<bshift d-size )
2911.10Seeh   2swap 2over d< r> or  if		( d-size )
2921.10Seeh      2drop r> fs-bsize l@ exit
2931.1Smrg   then
2941.10Seeh   r@ lfs-blkoff			( size.lo size.hi )
2951.10Seeh   r> lfs-fragroundup d>l		( size )
2961.10Seeh;
2971.10Seeh: lfs-fsbtodb ( fsb.lo fsb.hi fs -- db.lo db.hi )
2981.10Seeh    lfs_fsbtodb l@ d<<
2991.1Smrg;
3001.1Smrg
3011.10Seeh\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
3021.1Smrg\
3031.10Seeh\ The rest of the multi-filesystem stuff
3041.1Smrg\
3051.10Seeh\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
3061.1Smrg
3071.10Seeh\
3081.10Seeh\ FFS v1
3091.10Seeh\
3101.10Seeh: di-db-v1@ ( indx dinode -- db.lo db.hi )	di1_db swap la+ l@ l>d ;
3111.10Seeh: di-ib-v1@ ( indx dinode -- db.lo db.hi )	di1_ib swap la+ l@ l>d ;
3121.10Seeh: ib-ib-v1@ ( indx iblk -- db.lo db.hi )	swap la+ l@ l>d ;
3131.10Seeh
3141.10Seeh: cgbase ( cg fs -- daddr.lo daddr.hi ) fs_fpg l@ um* ;
3151.10Seeh: cgstart-ufs1 ( cg fs -- cgstart ) 
3161.10Seeh    2dup fs_old_cgmask l@ invert and		( cg fs stuff )
3171.10Seeh    over fs_old_cgoffset l@ um*			( cg fs off.lo off.hi )
3181.10Seeh    2swap cgbase d+				( off.lo off.hi )
3191.1Smrg;
3201.1Smrg
3211.1Smrg\
3221.10Seeh\ FFS v2
3231.1Smrg\
3241.1Smrg
3251.10Seeh: di-db-v2@ ( indx dinode -- db.lo db.hi )	di2_db swap 2* la+ d@ ;
3261.10Seeh: di-ib-v2@ ( indx dinode -- db.lo db.hi )	di2_ib swap 2* la+ d@ ;
3271.10Seeh: ib-ib-v2@ ( indx iblk -- db.lo db.hi )	2* la+ d@ ;
3281.1Smrg
3291.10Seeh\
3301.10Seeh\ LFS v1
3311.10Seeh\
3321.1Smrg
3331.1Smrg
3341.1Smrg\
3351.1Smrg\ File stuff
3361.1Smrg\
3371.1Smrg
3381.1Smrgniaddr /w* constant narraysize
3391.1Smrg
3401.10Seeh\ Assume UFS2 dinodes are always biger than UFS1
3411.10Seehufs2_dinode_SIZEOF buffer: cur-inode
3421.1Smrgh# 2000 buffer: indir-block
3431.10Seehcreate indir-addr -1 , -1 ,
3441.1Smrg
3451.1Smrg\
3461.1Smrg\ Translate a fileblock to a disk block
3471.1Smrg\
3481.10Seeh\ We don't do triple indirect blocks.
3491.1Smrg\
3501.1Smrg
3511.10Seeh\ Get the disk address from a single indirect block
3521.10Seeh: ib@ ( indx indir.lo indir.hi -- db.lo db.hi )
3531.10Seeh    2dup indir-addr d@ d<>  if		( indx indir.hi indir.lo )
3541.10Seeh	indir-addr d!			( indx )
3551.10Seeh	indir-block 			( indx indir-block )
3561.10Seeh	sb-buf fs-bsize l@		( indx indir-block fs fs-bsize )
3571.10Seeh	indir-addr d@ sb-buf		( indx indir-block fs-bsize indiraddr fs )
3581.10Seeh	fsbtodb 			( indx indir-block fs-bsize db.lo db.hi )
3591.10Seeh	strategy 0			( indx nread 0 ) \ Really should check return value
3601.10Seeh    then
3611.10Seeh    2drop				( indx )
3621.10Seeh    indir-block ib-ib@
3631.10Seeh;
3641.10Seeh
3651.10Seeh
3661.10Seeh: block-map ( fileblock -- diskblock.lo diskblock.hi )
3671.10Seeh    \ Direct block?
3681.10Seeh    dup ndaddr <  if			( fileblock )
3691.10Seeh	cur-inode di-db@ exit		( diskblock.lo diskblock.hi )
3701.10Seeh    then 				( fileblock )
3711.10Seeh    ndaddr -				( fileblock' )
3721.10Seeh    \ Now we need to check the indirect block
3731.10Seeh    dup sb-buf fs_nindir l@ <  if	( fileblock' )
3741.10Seeh	0 cur-inode di-ib@		( fileblock' indir.lo indir.hi )
3751.10Seeh	ib@ exit			( db.lo db.hi )
3761.1Smrg   then
3771.1Smrg   dup sb-buf fs_nindir -		( fileblock'' )
3781.1Smrg   \ Now try 2nd level indirect block -- just read twice 
3791.10Seeh   dup sb-buf fs_nindir l@ dup * >= if	( fileblock'' )
3801.10Seeh       ." block-map: exceeded max file size" cr
3811.10Seeh       abort
3821.1Smrg   then
3831.10Seeh       
3841.10Seeh   1 cur-inode di-ib@		( fileblock'' ib.lo ib.hi )
3851.10Seeh   
3861.10Seeh   \ Get 1st indirect block and find the 2nd indirect block
3871.10Seeh   rot dup sb-buf fs_nindir u/mod	( ib2.lo ib2.hi indx2 indx1 )
3881.10Seeh   2swap ib@			( indx2 ib2.lo ib2.hi )
3891.10Seeh   
3901.10Seeh   \ Get 2nd indirect block and find our diskblock
3911.10Seeh   ib@				( db.lo db.hi )
3921.1Smrg;
3931.1Smrg
3941.1Smrg\
3951.1Smrg\ Read file into internal buffer and return pointer and len
3961.1Smrg\
3971.1Smrg
3981.4Seeh0 value cur-block			\ allocated dynamically in ufs-open
3991.10Seeh0 value cur-blocksize			\ size allocated  to  cur-block
4001.10Seehcreate cur-blockno -1 l, -1 l,		\ Current disk block.
4011.10Seeh-1 value file-blockno			\ Current file block no.
4021.10Seeh0 value file-offset			\ Current file offset, max 4GB.
4031.10Seeh
4041.10Seeh: buf-read-file ( fs -- buf len )
4051.10Seeh    >r file-offset			( seek )
4061.10Seeh    dup l>d r@ lblkno drop		( seek blk )
4071.10Seeh    dup l>d cur-inode r@ blksize	( seek blk blksize )
4081.10Seeh    over file-blockno <> if		( seek blk blksize )
4091.10Seeh	over  to  file-blockno
4101.10Seeh	swap block-map			( seek blksize fsblk.lo fsblk.hi )
4111.10Seeh	2dup or 0=  if			( seek blksize fsblk.lo fsblk.hi )
4121.10Seeh	    \ Clear out curblock  XXX Why? Idunno.
4131.10Seeh	    2drop dup
4141.10Seeh	    cur-block swap erase	( seek blksize )
4151.10Seeh	    boot-debug?  if ." buf-read-file reading block 0" cr then
4161.10Seeh	    -1 l>d			\ Invalid disk block
4171.10Seeh	else
4181.10Seeh	    \ Call strategy to load the correct block.
4191.10Seeh	    r@ fsbtodb			( seek blksize dblk.lo dblk.hi )
4201.10Seeh	    rot >r cur-block r@ 2over	( seek addr size db.lo db.hi )
4211.10Seeh	    strategy r@	<>  if  ." buf-read-file: short read." cr abort  then
4221.10Seeh	    r> -rot			( seek size db.lo db.hi )
4231.10Seeh	then
4241.10Seeh	\ Save the new current disk block number
4251.10Seeh	cur-blockno d!			( seek size )
4261.10Seeh   else					
4271.10Seeh      nip				( seek size )
4281.10Seeh   then
4291.10Seeh   \ Now figure out how much we have in the buffer.
4301.10Seeh   swap l>d r> blkoff			( size off.lo off.hi )
4311.10Seeh   d>l cur-block over +			( size off buf )
4321.10Seeh   -rot -				( buf siz )
4331.1Smrg;
4341.1Smrg
4351.1Smrg\
4361.1Smrg\ Read inode into cur-inode -- uses cur-block
4371.1Smrg\ 
4381.1Smrg
4391.10Seeh: read-inode-ffs ( inode fs -- )
4401.10Seeh    twiddle
4411.10Seeh
4421.10Seeh    >r dup r@ ino-to-fsba		( ino fsblk.lo fsblck.hi )
4431.10Seeh    r@ fsbtodb				( ino dblk.lo dblk.hi )
4441.10Seeh    2dup cur-blockno d@ d<>  if		( ino dblk.lo dblk.hi )
4451.10Seeh	\ We need  to  read the block
4461.10Seeh	cur-block r@ fs-bsize l@	( ino dblk.lo dblk.hi addr size )
4471.10Seeh	>r r@ 2over strategy r> <> if	( ino dblk.lo dblk.hi )
4481.10Seeh	    ." read-inode - residual" cr abort
4491.10Seeh	then
4501.10Seeh	2dup cur-blockno d!		( ino dblk.lo dblk.hi )
4511.10Seeh    then 2drop				( ino )
4521.1Smrg
4531.10Seeh    r> ino-to-fsbo /dino *		( off )
4541.10Seeh    cur-block + cur-inode /dino move	( )
4551.10Seeh;
4561.10Seeh
4571.10Seeh: find-inode-sector ( ino fs -- d-dblkno true | false )
4581.10Seeh   >r r@ lfs_ifile l@ r@  read-inode	( ino )
4591.10Seeh
4601.10Seeh   r@ lfs_ifpb l@ u/mod			( rem q )
4611.10Seeh
4621.10Seeh   r@ lfs_cleansz l@ +
4631.10Seeh   r@ lfs_segtabsz l@ +			( rem blkno )
4641.1Smrg
4651.10Seeh   r@ fs-bsize l@ um* rot /ifile um* d+	( dseekp )
4661.1Smrg
4671.10Seeh   drop  to  file-offset r@ buf-read-file	( buf len )
4681.10Seeh
4691.10Seeh   /ifile <  if  r> 2drop false exit  then	( buf )
4701.10Seeh
4711.10Seeh   if_daddr l@ l>d r> fsbtodb		( daddr )
4721.10Seeh   2dup lfs_unused_daddr l>d d=  if  2drop false  then
4731.10Seeh   true
4741.10Seeh;
4751.10Seeh
4761.10Seeh: read-inode-lfs ( inode fs -- )
4771.10Seeh   twiddle
4781.10Seeh
4791.10Seeh   >r dup r@ lfs_ifile l@ =  if		( ino  r: fs )
4801.10Seeh      r@ lfs_idaddr l@ l>d		( ino d-idaddr )
4811.10Seeh      r@ fsbtodb			( ino d-db )
4821.10Seeh   else
4831.10Seeh      dup r@ find-inode-sector 0= abort" Could not find inode sector!"
4841.10Seeh   then					( ino d-db )
4851.10Seeh   
4861.10Seeh    2dup cur-blockno d@ d<>  if		( ino dblk.lo dblk.hi )
4871.10Seeh	\ We need to read the block
4881.10Seeh	cur-block r@ fs-bsize l@	( ino dblk.lo dblk.hi addr size )
4891.10Seeh	>r r@ 2over strategy r> <> if	( ino dblk.lo dblk.hi )
4901.10Seeh	    ." read-inode - residual" cr abort
4911.10Seeh	then
4921.10Seeh	2dup cur-blockno d!		( ino dblk.lo dblk.hi )
4931.10Seeh    then  2drop				( ino )
4941.10Seeh
4951.10Seeh    r@ lfs_inopb l@			( ino cnt )
4961.10Seeh    swap cur-block  begin		( cnt ino p )
4971.10Seeh       tuck di_inumber l@ over <>	( cnt p ino !found? )
4981.10Seeh    while				( cnt p ino )
4991.10Seeh	  rot 1- ?dup 0=  abort" Could not find inode!"
5001.10Seeh	  rot /dino + swap -rot		( cnt ino p )
5011.10Seeh    repeat  swap			( cnt ino p )
5021.10Seeh
5031.10Seeh    cur-inode /dino move		( cnt ino )
5041.10Seeh	  
5051.10Seeh    r> 3drop
5061.1Smrg;
5071.1Smrg
5081.1Smrg\ Identify inode type
5091.1Smrg
5101.10Seeh: is-dir? ( ufs1_dinode -- is-dir? )		di-mode w@ ifmt and ifdir = ;
5111.10Seeh: is-symlink? ( ufs1_dinode -- is-symlink? )	di-mode w@ ifmt and iflnk = ;
5121.10Seeh
5131.10Seeh\
5141.10Seeh\ Multi-FS initialiation.
5151.10Seeh\
5161.10Seeh\ It's way down here so all the fs-specific routines have already been defined.
5171.10Seeh\
5181.10Seeh
5191.10Seeh: init-ffs-common ( -- )
5201.10Seeh   ' fs_SIZEOF  to  fs-size 
5211.10Seeh   ' fs_bsize  to  fs-bsize
5221.10Seeh   ' ffs-dblksize  to  blksize
5231.10Seeh   ' read-inode-ffs  to  read-inode
5241.10Seeh   ' ffs-fsbtodb  to  fsbtodb
5251.10Seeh   ' ffs-lblkno  to  lblkno
5261.10Seeh   ' ffs-blkoff  to   blkoff
5271.10Seeh;   
5281.10Seeh
5291.10Seeh
5301.10Seeh: ffs-oldcompat ( -- )
5311.10Seeh   \ Make sure old ffs values in sb-buf are sane
5321.10Seeh   sb-buf fs_old_npsect dup l@ sb-buf fs_old_nsect l@ max swap l!
5331.10Seeh   sb-buf fs_old_interleave dup l@ 1 max swap l!
5341.10Seeh   sb-buf fs_old_postblformat l@ fs_42postblfmt =  if
5351.10Seeh      8 sb-buf fs_old_nrpos l!
5361.10Seeh   then
5371.10Seeh   sb-buf fs_old_inodefmt l@ fs_44inodefmt <  if
5381.10Seeh      sb-buf fs-bsize l@ 
5391.10Seeh      dup ndaddr um* 1 d- sb-buf fs_maxfilesize d!
5401.10Seeh      niaddr 0  ?do
5411.10Seeh	 sb-buf fs_nindir l@ * dup	( sizebp sizebp )
5421.10Seeh	 sb-buf fs_maxfilesize dup d@ ( sizebp sizebp *mxfs mxfs.lo mxfs.hi )
5431.10Seeh	 2over drop l>d d+ 2swap d!	( sizebp )
5441.10Seeh      loop  drop 			( )
5451.10Seeh      sb-buf dup fs_bmask l@ invert l>d rot fs_qbmask d!
5461.10Seeh      sb-buf dup fs_fmask l@ invert l>d rot fs_qfmask d!
5471.10Seeh   then
5481.10Seeh;
5491.10Seeh
5501.10Seeh
5511.10Seeh: init-ffs-v1 ( -- )
5521.10Seeh   init-ffs-common
5531.10Seeh   ' di1_size  to  di-size
5541.10Seeh   ' di1_mode  to  di-mode
5551.10Seeh   ' ufs1_dinode_SIZEOF  to  /dino
5561.10Seeh   ' cgstart-ufs1  to  cgstart
5571.10Seeh   ' di-db-v1@  to  di-db@
5581.10Seeh   ' di-ib-v1@  to  di-ib@
5591.10Seeh   ' ib-ib-v1@  to  ib-ib@
5601.10Seeh   ffs-oldcompat
5611.10Seeh;
5621.10Seeh
5631.10Seeh: init-ffs-v2 ( -- )
5641.10Seeh   init-ffs-common
5651.10Seeh   ' di2_size  to  di-size
5661.10Seeh   ' di2_mode  to  di-mode
5671.10Seeh   ' ufs2_dinode_SIZEOF  to  /dino
5681.10Seeh   ' cgbase  to  cgstart
5691.10Seeh   ' di-db-v2@  to  di-db@
5701.10Seeh   ' di-ib-v2@  to  di-ib@
5711.10Seeh   ' ib-ib-v2@  to  ib-ib@
5721.10Seeh;
5731.10Seeh
5741.10Seeh: init-lfs-common ( -- )
5751.10Seeh   ' dlfs_SIZEOF  to  fs-size 
5761.10Seeh   ' di1_size  to  di-size
5771.10Seeh   ' di1_mode  to  di-mode
5781.10Seeh   ' ufs1_dinode_SIZEOF  to  /dino
5791.10Seeh   ' cgbase  to  cgstart
5801.10Seeh   ' di-db-v1@  to  di-db@
5811.10Seeh   ' di-ib-v1@  to  di-ib@
5821.10Seeh   ' ib-ib-v1@  to  ib-ib@
5831.10Seeh   ' lfs-dblksize  to  blksize
5841.10Seeh   ' read-inode-lfs  to  read-inode
5851.10Seeh   ' lfs-fsbtodb  to  fsbtodb
5861.10Seeh   ' lfs-lblkno  to  lblkno
5871.10Seeh   ' lfs-blkoff  to  blkoff
5881.10Seeh;
5891.10Seeh
5901.10Seeh: init-lfs-v1 ( -- )
5911.10Seeh   init-lfs-common
5921.10Seeh   ' lfs_ibsize  to  fs-bsize
5931.10Seeh   ' ifile_v1_SIZEOF  to  /ifile
5941.10Seeh   ' if1_daddr  to  if_daddr
5951.10Seeh;   
5961.10Seeh
5971.10Seeh: init-lfs-v2 ( -- )
5981.10Seeh   init-lfs-common
5991.10Seeh   ' lfs_bsize  to  fs-bsize
6001.10Seeh   ' ifile_SIZEOF  to  /ifile
6011.10Seeh   ' if2_daddr  to  if_daddr
6021.10Seeh;   
6031.10Seeh
6041.10Seeh
6051.10Seeh: fs-magic? ( sb -- is-ufs? )
6061.10Seeh   \ The LFS magic is the first word in the superblock
6071.10Seeh   dup lfs_magic l@ lfs_magic_value =  if
6081.10Seeh      dup lfs_version l@  case		( sb sel )
6091.10Seeh	 1  of  init-lfs-v1 drop true exit  endof
6101.10Seeh	 2  of  init-lfs-v2 drop true exit  endof
6111.10Seeh	 ." Invalid LFS version."  \ Try FFS.
6121.10Seeh      endcase
6131.10Seeh   then					( sb )
6141.10Seeh   \ The FFS magic is at the end of the superblock
6151.11Seeh   \ XXX we should check to make sure this is not an alternate SB.
6161.10Seeh   fs_magic l@  case
6171.10Seeh      fs1_magic_value  of  init-ffs-v1 true  endof
6181.10Seeh      fs2_magic_value  of  init-ffs-v2 true  endof
6191.10Seeh      false swap	\ Return false
6201.10Seeh   endcase
6211.10Seeh;
6221.1Smrg
6231.1Smrg
6241.1Smrg
6251.1Smrg\
6261.1Smrg\ Hunt for directory entry:
6271.1Smrg\ 
6281.1Smrg\ repeat
6291.1Smrg\    load a buffer
6301.1Smrg\    while entries do
6311.1Smrg\       if entry == name return
6321.1Smrg\       next entry
6331.1Smrg\ until no buffers
6341.1Smrg\
6351.1Smrg
6361.10Seeh: search-dir-block ( str len buf len -- ino | 0 )
6371.10Seeh    2dup + nip				( str len buf bufend )
6381.10Seeh    swap 2swap rot			( bufend str len direct )
6391.10Seeh    begin  dup 4 pick <  while		( bufend str len direct )
6401.10Seeh	    dup d_ino l@ 0<>  if	( bufend str len direct )
6411.10Seeh		boot-debug?  if
6421.10Seeh		    \ Print the current file name
6431.10Seeh		    dup dup d_name swap d_namlen c@ type cr
6441.10Seeh		then
6451.10Seeh		2dup d_namlen c@ =  if	( bufend str len direct )
6461.10Seeh		    dup d_name 2over	( bufend str len direct dname str len )
6471.10Seeh		    comp 0= if		( bufend str len direct )
6481.10Seeh			\ Found it -- return inode
6491.10Seeh			d_ino l@ nip nip nip	( dino )
6501.10Seeh			boot-debug?  if  ." Found it" cr  then 
6511.10Seeh			exit 		( dino )
6521.10Seeh		    then
6531.10Seeh		then			( bufend str len direct )
6541.10Seeh	    then			( bufend str len direct )
6551.10Seeh	    dup d_reclen w@ +		( bufend str len nextdirect )
6561.10Seeh    repeat
6571.10Seeh    2drop 2drop 0
6581.10Seeh;
6591.10Seeh    
6601.10Seeh
6611.10Seeh: search-directory ( str len -- ino | 0 )
6621.10Seeh    0  to  file-offset
6631.10Seeh    begin
6641.10Seeh	file-offset cur-inode di-size d@ drop <
6651.10Seeh    while				( str len )
6661.10Seeh	    \ Read a directory block
6671.10Seeh	    sb-buf buf-read-file	( str len buf len )
6681.10Seeh	    dup 0=  if  ." search-directory: buf-read-file zero len" cr abort  then
6691.10Seeh	    dup file-offset +  to  file-offset	( str len buf len )
6701.10Seeh
6711.10Seeh	    2over 2swap search-dir-block ?dup  if
6721.10Seeh		\ Found it
6731.10Seeh		nip nip exit
6741.10Seeh	    then			( str len )
6751.10Seeh    repeat
6761.10Seeh    2drop 2drop 0			( 0 )
6771.1Smrg;
6781.1Smrg
6791.3Seeh: read-super ( sector -- )
6801.10Seeh   0 " seek" boot-ihandle $call-method -1 =  if 
6811.10Seeh      ." Seek failed" cr abort
6821.1Smrg   then
6831.1Smrg   sb-buf sbsize " read" boot-ihandle $call-method
6841.1Smrg   dup sbsize <>  if
6851.1Smrg      ." Read of superblock failed" cr
6861.1Smrg      ." requested" space sbsize .
6871.1Smrg      ." actual" space . cr
6881.1Smrg      abort
6891.1Smrg   else 
6901.1Smrg      drop
6911.1Smrg   then
6921.3Seeh;
6931.3Seeh
6941.11Seeh: check-supers ( -- found? )
6951.11Seeh   \ Superblocks used to be 8KB into the partition, but ffsv2 changed that.
6961.11Seeh   \ See comments in src/sys/ufs/ffs/fs.h
6971.11Seeh   \ Put a list of offets to check on the stack, ending with -1
6981.11Seeh   -1
6991.11Seeh   0
7001.11Seeh   d# 128 KB
7011.11Seeh   d# 64 KB
7021.11Seeh   8 KB
7031.11Seeh   
7041.11Seeh   begin  dup -1 <>  while			( -1 .. off )
7051.11Seeh	 raid-offset dev_bsize * + read-super	( -1 .. )
7061.11Seeh	 sb-buf fs-magic?  if			( -1 .. )
7071.11Seeh	    begin  -1 =  until	 \ Clean out extra stuff from stack
7081.11Seeh	    true exit
7091.11Seeh	 then
7101.11Seeh   repeat
7111.11Seeh   drop false
7121.11Seeh;
7131.11Seeh
7141.10Seeh: ufs-open ( bootpath len -- )
7151.3Seeh   boot-ihandle -1 =  if
7161.10Seeh      2dup + 0 swap c!	\ Nul terminate.
7171.10Seeh      over cif-open dup 0=  if 	( boot-path len ihandle? )
7181.10Seeh	 ." Could not open device" space type cr 
7191.10Seeh	 abort
7201.3Seeh      then 				( boot-path len ihandle )
7211.10Seeh      to  boot-ihandle			\ Save ihandle to boot device
7221.10Seeh   then
7231.10Seeh   2drop
7241.10Seeh   
7251.10Seeh   boot-debug?  if ." Try a RAID superblock read" cr  then
7261.11Seeh   \ RAIDFRAME skips 64 sectors.
7271.11Seeh   d# 64  to  raid-offset
7281.11Seeh   check-supers invert  if
7291.10Seeh      boot-debug?  if ." Try a normal superblock read" cr  then
7301.10Seeh      0  to  raid-offset 
7311.11Seeh      check-supers 0=  abort" Invalid superblock magic"
7321.1Smrg   then
7331.10Seeh   sb-buf fs-bsize l@ dup maxbsize >  if
7341.1Smrg      ." Superblock bsize" space . ." too large" cr
7351.1Smrg      abort
7361.1Smrg   then 
7371.10Seeh   dup fs-size <  if
7381.1Smrg      ." Superblock bsize < size of superblock" cr
7391.1Smrg      abort
7401.1Smrg   then
7411.10Seeh   dup  to  cur-blocksize alloc-mem  to  cur-block    \ Allocate cur-block
7421.10Seeh   boot-debug?  if  ." ufs-open complete" cr  then
7431.1Smrg;
7441.1Smrg
7451.1Smrg: ufs-close ( -- ) 
7461.10Seeh    boot-ihandle dup -1 <>  if
7471.10Seeh	cif-close -1  to  boot-ihandle 
7481.10Seeh    then
7491.10Seeh    cur-block 0<> if
7501.10Seeh	cur-block cur-blocksize free-mem
7511.10Seeh    then
7521.1Smrg;
7531.1Smrg
7541.1Smrg: boot-path ( -- boot-path )
7551.10Seeh    " bootpath" chosen-phandle get-package-property  if
7561.10Seeh	." Could not find bootpath in /chosen" cr
7571.10Seeh	abort
7581.10Seeh    else
7591.10Seeh	decode-string 2swap 2drop
7601.10Seeh    then
7611.1Smrg;
7621.1Smrg
7631.1Smrg: boot-args ( -- boot-args )
7641.10Seeh    " bootargs" chosen-phandle get-package-property  if
7651.10Seeh	." Could not find bootargs in /chosen" cr
7661.10Seeh	abort
7671.10Seeh    else
7681.10Seeh	decode-string 2swap 2drop
7691.10Seeh    then
7701.1Smrg;
7711.1Smrg
7721.1Smrg2000 buffer: boot-path-str
7731.1Smrg2000 buffer: boot-path-tmp
7741.1Smrg
7751.1Smrg: split-path ( path len -- right len left len )
7761.1Smrg\ Split a string at the `/'
7771.10Seeh    begin
7781.10Seeh	dup -rot				( oldlen right len left )
7791.10Seeh	ascii / left-parse-string		( oldlen right len left len )
7801.10Seeh	dup 0<>  if  4 roll drop exit  then
7811.10Seeh	2drop					( oldlen right len )
7821.10Seeh	rot over =				( right len diff )
7831.10Seeh    until
7841.1Smrg;
7851.1Smrg
7861.1Smrg: find-file ( load-file len -- )
7871.10Seeh    rootino dup sb-buf read-inode	( load-file len pino )
7881.10Seeh    -rot				( pino load-file len )
7891.10Seeh    \
7901.10Seeh    \ For each path component
7911.10Seeh    \ 
7921.10Seeh    begin  split-path dup 0<>  while	( pino right len left len )
7931.10Seeh	    cur-inode is-dir? not  if  ." Inode not directory" cr abort  then
7941.10Seeh	    boot-debug?  if  ." Looking for" space 2dup type space ." in directory..." cr  then
7951.10Seeh	    search-directory		( pino right len ino|false )
7961.10Seeh	    dup 0=  abort" Bad path" 	( pino right len cino )
7971.10Seeh	    sb-buf read-inode			( pino right len )
7981.10Seeh	    cur-inode is-symlink?  if		\ Symlink -- follow the damn thing
7991.10Seeh		\ Save path in boot-path-tmp
8001.10Seeh		boot-path-tmp strmov		( pino new-right len )
8011.10Seeh		
8021.10Seeh		\ Now deal with symlink  XXX drop high word of linklen
8031.10Seeh		cur-inode di-size d@ drop	( pino right len linklen.lo )
8041.10Seeh		dup sb-buf fs_maxsymlinklen l@	( pino right len linklen linklen maxlinklen )
8051.10Seeh		<  if				\ Now join the link to the path
8061.10Seeh		    0 cur-inode di-db@ drop	( pino right len linklen linkp )
8071.10Seeh		    swap boot-path-str strmov	( pino right len new-linkp linklen )
8081.10Seeh		else				\ Read file for symlink -- Ugh
8091.10Seeh		    \ Read link into boot-path-str
8101.10Seeh		    boot-path-str dup sb-buf fs-bsize l@
8111.10Seeh		    0 block-map			( pino right len linklen boot-path-str bsize blockno.lo blockno.hi )
8121.10Seeh		    strategy drop swap		( pino right len boot-path-str linklen )
8131.10Seeh		then 				( pino right len linkp linklen )
8141.10Seeh		\ Concatenate the two paths
8151.10Seeh		strcat				( pino new-right newlen )
8161.10Seeh		swap dup c@ ascii / =  if	\ go to root inode?
8171.10Seeh		    rot drop rootino -rot	( rino len right )
8181.10Seeh		then
8191.10Seeh		rot dup sb-buf read-inode	( len right pino )
8201.10Seeh		-rot swap			( pino right len )
8211.10Seeh	    then				( pino right len )
8221.10Seeh    repeat
8231.10Seeh    2drop drop
8241.10Seeh;
8251.10Seeh
8261.10Seeh: .read-file-msg ( addr xxx siz -- addr xxx siz )
8271.10Seeh    boot-debug? if
8281.10Seeh	." Copying " dup . ." bytes to " 3 pick . cr
8291.10Seeh    then
8301.10Seeh;
8311.10Seeh       
8321.10Seeh: read-file ( addr size -- )
8331.10Seeh    noop \ In case we need to debug this
8341.10Seeh    \ Read x bytes from a file to buffer
8351.10Seeh    begin  dup 0>  while
8361.10Seeh	    file-offset cur-inode di-size d@ drop >  if
8371.10Seeh		." read-file EOF exceeded" cr abort
8381.10Seeh	    then
8391.10Seeh	    sb-buf buf-read-file		( addr size buf len )
8401.10Seeh	    
8411.10Seeh	    .read-file-msg
8421.10Seeh	    
8431.10Seeh	    \ Copy len bytes to addr  XXX min ( len, size ) ?
8441.10Seeh	    2over drop 3dup swap move drop	( addr size buf len )
8451.10Seeh	    
8461.10Seeh	    dup file-offset +  to  file-offset	( addr size buf len )
8471.10Seeh	    
8481.10Seeh	    nip tuck - -rot + swap		( addr' size' )
8491.10Seeh    repeat
8501.10Seeh    2drop
8511.1Smrg;
8521.1Smrg
8531.10Seeh" load-base " evaluate constant loader-base
8541.1Smrg
8551.1Smrg: load-file-signon ( load-file len boot-path len -- load-file len boot-path len )
8561.1Smrg   ." Loading file" space 2over type cr ." from device" space 2dup type cr
8571.1Smrg;
8581.1Smrg
8591.1Smrg: load-file ( load-file len boot-path len -- load-base )
8601.10Seeh   boot-debug?  if  load-file-signon  then
8611.10Seeh   
8621.10Seeh   ufs-open 				( load-file len )
8631.10Seeh   find-file				( )
8641.1Smrg
8651.10Seeh    \
8661.10Seeh    \ Now we've found the file we should read it in in one big hunk
8671.10Seeh    \
8681.10Seeh    
8691.10Seeh    cur-inode di-size d@  if  ." File len >2GB!" cr abort  then
8701.10Seeh\    dup " to file-size " evaluate	( file-len ) \ Wassthis?
8711.10Seeh    boot-debug?  if
8721.10Seeh	." Loading " dup . ."  bytes of file..." cr
8731.10Seeh    then
8741.10Seeh    0  to  file-offset
8751.10Seeh    -1  to  file-blockno
8761.10Seeh    loader-base				( buf-len addr )
8771.10Seeh    tuck swap read-file			( addr )
8781.10Seeh    ufs-close				( addr )
8791.1Smrg;
8801.1Smrg
8811.1Smrg: do-boot ( bootfile -- )
8821.11Seeh   ." NetBSD IEEE 1275 Multi-FS Bootblock" cr
8831.11Seeh   ." Version $NetBSD: bootblk.fth,v 1.11 2010/02/17 15:49:19 eeh Exp $" cr
8841.11Seeh   boot-path load-file ( -- load-base )
8851.11Seeh   dup 0<>  if  " init-program " evaluate  then
8861.10Seeh; 
8871.1Smrg
8881.1Smrg
8891.10Seehboot-args ascii V strchr 0<> swap drop  if
8901.10Seeh    true  to  boot-debug?
8911.1Smrgthen
8921.1Smrg
8931.10Seehboot-args ascii D strchr 0= swap drop  if
8941.10Seeh    " /ofwboot" do-boot
8951.10Seehthen  exit
8961.1Smrg
8971.1Smrg
898