15648Ssetje\ 25648Ssetje\ CDDL HEADER START 35648Ssetje\ 45648Ssetje\ The contents of this file are subject to the terms of the 55648Ssetje\ Common Development and Distribution License (the "License"). 65648Ssetje\ You may not use this file except in compliance with the License. 75648Ssetje\ 85648Ssetje\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95648Ssetje\ or http://www.opensolaris.org/os/licensing. 105648Ssetje\ See the License for the specific language governing permissions 115648Ssetje\ and limitations under the License. 125648Ssetje\ 135648Ssetje\ When distributing Covered Code, include this CDDL HEADER in each 145648Ssetje\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155648Ssetje\ If applicable, add the following below this CDDL HEADER, with the 165648Ssetje\ fields enclosed by brackets "[]" replaced with your own identifying 175648Ssetje\ information: Portions Copyright [yyyy] [name of copyright owner] 185648Ssetje\ 195648Ssetje\ CDDL HEADER END 205648Ssetje\ 215648Ssetje\ 22*9941SJohn.Johnson@Sun.COM\ Copyright 2009 Sun Microsystems, Inc. All rights reserved. 235648Ssetje\ Use is subject to license terms. 245648Ssetje\ 255648Ssetje 265648Ssetjepurpose: boot block for OBP systems 27*9941SJohn.Johnson@Sun.COMcopyright: Copyright 2009 Sun Microsystems, Inc. All Rights Reserved 285648Ssetje 295648Ssetje 305648Ssetjeheaderless 315648Ssetjed# 1024 dup * constant 1meg 325648Ssetjed# 4 1meg * constant 4meg 335648Ssetjed# 32 1meg * constant 32meg 345648Ssetje 355648Ssetjeheaders 365648Ssetje" /" get-package constant root-ph 375648Ssetje 385648Ssetje0 value fs-ih 395648Ssetjefalse value nested? 405648Ssetje0 value file-sz 415648Ssetje 425648Ssetje/buf-len buffer: boot-dev 435648Ssetje: boot-dev$ ( -- dev$ ) boot-dev cscount ; 445648Ssetje 455648Ssetje: loader-base ( -- base ) 465648Ssetje nested? if 475648Ssetje h# 5000.0000 485648Ssetje else 495648Ssetje h# 5100.0000 505648Ssetje then 515648Ssetje; 525648Ssetje 535648Ssetje 545648Ssetje\ 555648Ssetje\ methods we expect of fs reader packages 565648Ssetje\ 575648Ssetjeheaderless 585648Ssetje: fs-open ( file$ -- fd true | false ) 595648Ssetje " open-file" fs-ih $call-method 605648Ssetje; 615648Ssetje 625648Ssetje: fs-close ( fd -- ) 635648Ssetje " close-file" fs-ih $call-method 645648Ssetje; 655648Ssetje 665648Ssetje: fs-size ( fd -- size ) 675648Ssetje " size-file" fs-ih $call-method 685648Ssetje; 695648Ssetje 705648Ssetje: fs-read ( adr len fd -- #read ) 715648Ssetje " read-file" fs-ih $call-method 725648Ssetje; 735648Ssetje 745648Ssetje: fs-getrd ( adr len -- ) 755648Ssetje " get-rd" fs-ih $call-method 765648Ssetje; 775648Ssetje 785648Ssetje: fs-bootprop ( -- propval propname true | false ) 795648Ssetje " bootprop" fs-ih $call-method 805648Ssetje; 815648Ssetjeheaders 825648Ssetje 835648Ssetje 847283Sjgj: check-elf ( base -- is-elf? ) 857283Sjgj l@ h# 7f454c46 ( \x7fELF ) = 867283Sjgj; 877283Sjgj 887283Sjgj: check-fcode ( base -- is-fcode? ) 897283Sjgj c@ dup h# f0 h# f3 between swap h# fd = or 907283Sjgj; 917283Sjgj 927283Sjgj 935648Ssetje\ zfs bootblks with all headers exceeds 7.5k 945648Ssetje\ 'bigbootblk' allows us to load the fs reader from elsewhere 955648Ssetje[ifdef] bigbootblk 965648Ssetje 975648Ssetje: load-pkg ( -- ) 987283Sjgj boot-dev$ ( dev$ ) 997283Sjgj 2dup dev-open ?dup 0= if 1005648Ssetje open-abort 1015648Ssetje then >r 2drop ( r: ih ) 1027283Sjgj 1035648Ssetje /fs-fcode mem-alloc ( adr r: ih ) 1045648Ssetje dup /fs-fcode fs-offset r@ read-disk 1057283Sjgj 1067283Sjgj dup check-fcode invert if 1077283Sjgj " No fs fcode found" die 1087283Sjgj then 1095648Ssetje dup 1 byte-load 1107283Sjgj 1115648Ssetje /fs-fcode mem-free ( r: ih ) 1125648Ssetje r> dev-close 1135648Ssetje; 1145648Ssetje 1155648Ssetje[else] 1165648Ssetje 1175648Ssetje: load-pkg ( -- ) ; 1185648Ssetje 1195648Ssetje[then] 1205648Ssetje 1215648Ssetje 1225648Ssetje: get-bootdev ( -- ) 1235648Ssetje \ first try boot archive (nested boot from ramdisk) 1245648Ssetje \ then try boot device (direct boot from disk) 1255648Ssetje " bootarchive" chosen-ph get-package-property if 1265648Ssetje " bootpath" chosen-ph get-string-prop ( bootpath$ ) 1275648Ssetje else ( archiveprop$ ) 1285648Ssetje decode-string 2swap 2drop ( archivepath$ ) 1295648Ssetje true to nested? 1305648Ssetje then ( bootpath$ ) 1315648Ssetje boot-dev swap move ( ) 1325648Ssetje; 1335648Ssetje 1345648Ssetje: mount-root ( -- ) 1355648Ssetje boot-dev$ fs-pkg$ $open-package to fs-ih 1365648Ssetje fs-ih 0= if 1376423Sgw25295 " Can't mount root" die 1385648Ssetje then 1395648Ssetje; 1405648Ssetje 1415648Ssetje\ 1425648Ssetje\ cheap entertainment for those watching 1435648Ssetje\ boot progress 1445648Ssetje\ 1455648Ssetjeheaderless 1465648Ssetjecreate spin-data 1475648Ssetje ascii | c, ascii / c, ascii - c, ascii \ c, 1485648Ssetje 149*9941SJohn.Johnson@Sun.COMvariable spindex 1505648Ssetje 151*9941SJohn.Johnson@Sun.COMheaders 1525648Ssetje: spinner ( -- ) 1535648Ssetje spindex @ 3 and spin-data + ( c-adr ) 1545648Ssetje c@ emit (cr 1555648Ssetje 1 spindex +! 1565648Ssetje; 1575648Ssetje 1585648Ssetje\ allocate and return physical allocation size 1595648Ssetje: vmem-alloc-prop ( size virt -- alloc-size virt ) 1605648Ssetje 2dup ['] vmem-alloc catch if ( size virt ??? ??? ) 1615648Ssetje 2drop ( size virt ) 1625648Ssetje 2dup begin ( size virt len adr ) 1635648Ssetje over 32meg min >r ( size virt len adr r: alloc-sz ) 1645648Ssetje r@ over vmem-alloc ( size virt len adr adr r: alloc-sz ) 1655648Ssetje nip r@ + ( size virt len adr' r: alloc-sz ) 1665648Ssetje swap r> - ( size virt adr len' ) 1676490Sjgj swap over 0= ( size virt len' adr done? ) 1686490Sjgj until ( size virt len' adr ) 1695648Ssetje 2drop nip 32meg ( virt 32meg ) 1705648Ssetje else ( size virt virt ) 1715648Ssetje nip nip 0 ( virt 0 ) 1725648Ssetje then ( virt alloc-sz ) 1735648Ssetje swap 1745648Ssetje; 1755648Ssetje 176*9941SJohn.Johnson@Sun.COM\ read file in chunks so we can toggle the spinner 177*9941SJohn.Johnson@Sun.COM: read-file ( virt size fd -- failed? ) 178*9941SJohn.Johnson@Sun.COM >r ( virt sz-left r: fd ) 179*9941SJohn.Johnson@Sun.COM begin dup while 180*9941SJohn.Johnson@Sun.COM spinner 181*9941SJohn.Johnson@Sun.COM dup 4meg min ( virt sz-left read-sz r: fd ) 182*9941SJohn.Johnson@Sun.COM 3dup nip r@ fs-read ( virt sz-left read-sz size-read r: fd ) 183*9941SJohn.Johnson@Sun.COM over <> if ( virt sz-left read-sz r: fd ) 184*9941SJohn.Johnson@Sun.COM r> 2drop 2drop ( ) 185*9941SJohn.Johnson@Sun.COM true exit ( failed ) 186*9941SJohn.Johnson@Sun.COM then 187*9941SJohn.Johnson@Sun.COM rot over + ( sz-left read-sz virt' r: fd ) 188*9941SJohn.Johnson@Sun.COM -rot - ( virt' sz-left' r: fd ) 189*9941SJohn.Johnson@Sun.COM repeat 190*9941SJohn.Johnson@Sun.COM r> 3drop ( ) 191*9941SJohn.Johnson@Sun.COM false ( succeeded ) 192*9941SJohn.Johnson@Sun.COM; 193*9941SJohn.Johnson@Sun.COM 1945648Ssetje\ read in file and return buffer 1955648Ssetje\ if base==0, vmem-alloc will allocate virt 1966490Sjgj\ NB returned size is 8k rounded since the 1976490Sjgj\ memory allocator rounded it for us 1986490Sjgj: get-file ( base fd -- [ alloc-sz virt size ] failed? ) 1995648Ssetje dup >r fs-size ( base size r: fd ) 2005648Ssetje dup rot vmem-alloc-prop ( size alloc-sz virt r: fd ) 201*9941SJohn.Johnson@Sun.COM rot 2dup ( alloc-sz virt size virt size r: fd ) 202*9941SJohn.Johnson@Sun.COM r> read-file if ( alloc-sz virt size ) 2035648Ssetje 3drop true exit ( failed ) 2045648Ssetje then 2056490Sjgj h# 2000 roundup ( alloc-sz virt size' ) 2066490Sjgj false ( alloc-sz virt size' succeeded ) 2075648Ssetje; 2085648Ssetje 2095648Ssetje 2105648Ssetjefalse value is-elf? 2115648Ssetjefalse value is-archive? 2125648Ssetje 2135648Ssetje 2145648Ssetje: >bootblk ( adr -- adr' ) d# 512 + ; 2155648Ssetje 2165648Ssetje\ figure out what we just loaded 2175648Ssetje: get-type ( adr -- ) 2185648Ssetje dup check-elf to is-elf? 2195648Ssetje 2205648Ssetje \ if not nested, check for boot archive (executable after label) 2215648Ssetje nested? invert if 2225648Ssetje >bootblk 2235648Ssetje dup check-fcode ( adr is-fcode? ) 2245648Ssetje over check-elf ( adr is-fcode? is-elf? ) 2255648Ssetje or to is-archive? 2265648Ssetje then 2275648Ssetje drop 2285648Ssetje; 2295648Ssetje 2305648Ssetje 2315648Ssetje\ 2325648Ssetje\ file name routines 2335648Ssetje\ 2345648Ssetje 2355648Ssetje\ boot file (-F name or boot archive) 2365648Ssetjefalse value fflag? 2375648Ssetje/buf-len buffer: boot-file 2385648Ssetje: boot-file$ ( -- file$ ) boot-file cscount ; 2395648Ssetje 2405648Ssetje\ kernel name (final name or unix) 2415648Ssetjefalse value kern? 2425648Ssetje/buf-len buffer: kern-file 2435648Ssetje: kern-file$ ( -- file$ ) kern-file cscount ; 2445648Ssetje 2455648Ssetje\ platform name 2465648Ssetje/buf-len buffer: plat-name 2475648Ssetje: plat-name$ ( -- plat$ ) plat-name cscount ; 2485648Ssetje 2495648Ssetje\ arch name 2505648Ssetje/buf-len buffer: arch-name 2515648Ssetje: arch-name$ ( -- arch$ ) arch-name cscount ; 2525648Ssetje 2535648Ssetje\ final name after /platform massaging 2545648Ssetje/buf-len buffer: targ-file 2555648Ssetje: targ-file$ ( -- file$ ) targ-file cscount ; 2565648Ssetje 2575648Ssetje: init-targ ( -- ) 2585648Ssetje targ-file /buf-len erase 2595648Ssetje " /platform/" targ-file swap move 2605648Ssetje; 2615648Ssetje 2625648Ssetje\ remove illegal file name chars (e.g., '/') 2635648Ssetje: munge-name ( name$ -- name$' ) 2645648Ssetje 2dup ( name$ name$ ) 2655648Ssetje begin dup while 2665648Ssetje over c@ ascii / = if 2675648Ssetje over ascii _ swap c! ( name$ name$' ) 2685648Ssetje then str++ 2695648Ssetje repeat 2drop ( name$ ) 2705648Ssetje; 2715648Ssetje 2725726Sjgj\ does /platform/<name> exist? 2735726Sjgj: try-platname ( name$ -- name$ true | false ) 2745726Sjgj munge-name ( name$' ) 2755726Sjgj init-targ 2dup targ-file$ $append 2765726Sjgj targ-file$ fs-open if ( name$ fd ) 2775726Sjgj fs-close true ( name$ true ) 2785726Sjgj else ( name$ ) 2795726Sjgj 2drop false ( false ) 2805726Sjgj then ( name$ true | false ) 2815726Sjgj; 2825726Sjgj 2835726Sjgj\ setup arch-name 2845726Sjgj\ sun4v -or- sun4u 2855726Sjgj: get-def-arch ( -- ) 2865648Ssetje " device_type" root-ph get-package-property if 2875648Ssetje \ some older sunfires don't have device_type set 2885648Ssetje false ( sun4u ) 2895648Ssetje else ( devtype-prop$ ) 2905648Ssetje decode-string 2swap 2drop ( devtype$ ) 2915648Ssetje " sun4v" $= ( sun4v? ) 2925648Ssetje then ( sun4v? ) 2935648Ssetje if " sun4v" else " sun4u" then ( arch$ ) 2945648Ssetje arch-name swap move 2955726Sjgj; 2965726Sjgj 2975726Sjgj\ setup plat-name 2985726Sjgj\ platform name -or- 2995726Sjgj\ compatible name -or- 3005726Sjgj\ default name 3015726Sjgj: get-arch ( -- ) 3025726Sjgj get-def-arch 3035726Sjgj 3045726Sjgj \ first try "name" in root 3055726Sjgj " name" root-ph get-string-prop ( name$ ) 3065726Sjgj try-platname if 3075726Sjgj plat-name swap move exit ( ) 3085726Sjgj then ( ) 3095726Sjgj 3105726Sjgj \ next try "compatible" 3115726Sjgj " compatible" root-ph ( prop$ ph ) 3125726Sjgj get-package-property invert if ( compat$ ) 3135726Sjgj begin decode-string dup while ( compat$ name$ ) 3145726Sjgj try-platname if 3155726Sjgj plat-name swap move 2drop exit ( ) 3165726Sjgj then ( compat$ ) 3175726Sjgj repeat 2drop 2drop ( ) 3185726Sjgj then ( ) 3195726Sjgj 3205726Sjgj \ else use default name 3215726Sjgj arch-name$ plat-name swap move 3225648Ssetje; 3235648Ssetje 3245648Ssetje\ make <pre> <file> into /platform/<pre>/<file> 3255648Ssetje: $plat-prepend ( file$ pre$ -- file$' ) 3265648Ssetje init-targ 3275648Ssetje targ-file$ $append ( file$ ) 3285648Ssetje " /" targ-file$ $append 3295648Ssetje targ-file$ $append ( ) 3305648Ssetje targ-file$ ( new$ ) 3315648Ssetje; 3325648Ssetje 3335648Ssetje: get-boot ( -- file$ ) 3345648Ssetje fflag? if 3355648Ssetje boot-file$ 3365648Ssetje else 3375648Ssetje " boot_archive" 3385648Ssetje then 3395648Ssetje; 3405648Ssetje 3415648Ssetje: get-kern ( -- file$ ) 3425648Ssetje kern? if 3435648Ssetje kern-file$ 3445648Ssetje else 3455648Ssetje " kernel/sparcv9/unix" 3465648Ssetje then 3475648Ssetje; 3485648Ssetje 3495648Ssetje\ if we're nested, load the kernel, else load the bootarchive 3505648Ssetje: get-targ ( -- file$ ) 3515648Ssetje nested? if 3525648Ssetje get-kern 3535648Ssetje else 3545648Ssetje get-boot 3555648Ssetje then 3565648Ssetje; 3575648Ssetje 3585648Ssetje 3595648Ssetje: try-file ( file$ -- [ fd ] error? ) 3605648Ssetje diagnostic-mode? if 3615648Ssetje 2dup ." Loading: " type cr 3625648Ssetje then 3635648Ssetje fs-open invert ( fd false | true ) 3645648Ssetje; 3655648Ssetje 3665648Ssetje\ try "/platform/<plat-name>/<file>" e.g., SUNW,Sun-Blade-1000 3675648Ssetje\ then "/platform/<arch-name>/<file>" e.g., sun4u 3685648Ssetje: open-path ( file$ - fd ) 3695648Ssetje over c@ ascii / <> if 3705648Ssetje 2dup plat-name$ $plat-prepend ( file$ file$' ) 3715648Ssetje try-file if ( file$ ) 3725648Ssetje 2dup arch-name$ $plat-prepend ( file$ file$' ) 3735648Ssetje try-file if ( file$ ) 3745648Ssetje open-abort 3755648Ssetje then ( file$ fd ) 3765648Ssetje then ( file$ fd ) 3775648Ssetje else ( file$ ) 3785648Ssetje \ copy to targ-file for 'whoami' prop 3795648Ssetje targ-file /buf-len erase 3805648Ssetje 2dup targ-file swap move 3815648Ssetje 2dup try-file if ( file$ ) 3825648Ssetje open-abort 3835648Ssetje then ( file$ fd ) 3845648Ssetje then ( file$ fd ) 3855648Ssetje -rot 2drop ( fd ) 3865648Ssetje; 3875648Ssetje 3885648Ssetje 3896423Sgw25295false value lflag? 3906423Sgw25295 3915648Ssetje\ ZFS support 3925648Ssetje\ -Z fsname opens specified filesystem in disk pool 3935648Ssetje 3945648Ssetjefalse value zflag? 3955648Ssetje/buf-len buffer: fs-name 3965648Ssetje: fs-name$ ( -- fs$ ) fs-name cscount ; 3975648Ssetje 3985648Ssetje[ifdef] zfs 3995648Ssetje 4005648Ssetje: open-zfs-fs ( fs$ -- ) 4015648Ssetje 2dup " open-fs" fs-ih $call-method 0= if 4025648Ssetje open-abort 4035648Ssetje then 4045648Ssetje 2drop ( ) 4055648Ssetje; 4065648Ssetje 4075648Ssetje[else] 4085648Ssetje 4095648Ssetje: open-zfs-fs ( fs$ -- ) 4106423Sgw25295 \ ignore on -L 4116423Sgw25295 lflag? invert if 4126423Sgw25295 " -Z not supported on non-zfs root" die 4136423Sgw25295 then 4145648Ssetje; 4155648Ssetje 4165648Ssetje[then] 4175648Ssetje 4185648Ssetje 4195648Ssetje\ 4205648Ssetje\ arg parsing 4215648Ssetje\ 4225648Ssetje 4235648Ssetjeheaderless 4245648Ssetje: printable? ( n -- flag ) \ true if n is a printable ascii character 4255648Ssetje dup bl th 7f within swap th 80 th ff between or 4265648Ssetje; 4275648Ssetje: white-space? ( n -- flag ) \ true is n is non-printable? or a blank 4285648Ssetje dup printable? 0= swap bl = or 4295648Ssetje; 4305648Ssetje 4315648Ssetje: skip-blanks ( adr len -- adr' len' ) 4325648Ssetje begin dup while ( adr' len' ) 4335648Ssetje over c@ white-space? 0= if exit then 4345648Ssetje str++ 4355648Ssetje repeat 4365648Ssetje; 4375648Ssetje 4385648Ssetje: skip-non-blanks ( adr len -- adr' len' ) 4395648Ssetje begin dup while ( adr' len' ) 4405648Ssetje over c@ white-space? if exit then 4415648Ssetje str++ 4425648Ssetje repeat 4435648Ssetje; 4445648Ssetje 4455648Ssetjeheaders 4465648Ssetje\ left-parse-string w/ any white space as delimeter 4475648Ssetje: next-str ( adr len -- adr' len' s-adr s-len ) 4485648Ssetje 2dup skip-non-blanks ( s-adr len adr' len' ) 4495648Ssetje dup >r 2swap r> - ( adr' len' s-adr s-len ) 4505648Ssetje; 4515648Ssetje 452*9941SJohn.Johnson@Sun.COM\ next char or 0 if eol 4535648Ssetje: next-c ( adr len -- adr' len' c ) 454*9941SJohn.Johnson@Sun.COM dup if over c@ >r str++ r> else 0 then 4555648Ssetje; 4565648Ssetje 4575648Ssetjefalse value halt? 4585648Ssetje 4595648Ssetje: parse-bootargs ( -- ) 4605648Ssetje " bootargs" chosen-ph get-string-prop ( arg$ ) 4615648Ssetje 4625648Ssetje \ check for explicit kernel name 4635648Ssetje skip-blanks dup if 4645648Ssetje over c@ ascii - <> if 4655648Ssetje next-str ( arg$ kern$ ) 4665648Ssetje \ use default kernel if user specific a debugger 4675648Ssetje 2dup " kadb" $= >r ( arg$ kern$ r: kadb? ) 4685648Ssetje 2dup " kmdb" $= r> or ( arg$ kern$ debugger? ) 4695648Ssetje invert if ( arg$ kern$ ) 4705648Ssetje kern-file swap move ( arg$ ) 4715648Ssetje true to kern? 4725648Ssetje else 2drop then ( arg$ ) 4735648Ssetje then 4745648Ssetje then 4755648Ssetje 4765648Ssetje \ process args 4775648Ssetje begin 4785648Ssetje skip-blanks dup ( arg$ len ) 4795648Ssetje while 4805648Ssetje next-c ascii - = if 4815648Ssetje next-c case 4825648Ssetje ascii D of 4835648Ssetje \ for "boot kadb -D kernel.foo/unix" 4845648Ssetje skip-blanks next-str ( arg$ file$ ) 4855648Ssetje kern? invert if 4865648Ssetje ?dup if 4875648Ssetje kern-file swap move ( arg$ ) 4885648Ssetje true to kern? 4895648Ssetje else drop then ( arg$ ) 4905648Ssetje else 2drop then ( arg$ ) 4915648Ssetje endof 4925648Ssetje ascii F of 4935648Ssetje skip-blanks next-str ( arg$ file$ ) 4945648Ssetje ?dup if 4955648Ssetje boot-file swap move ( arg$ ) 4965648Ssetje true to fflag? 4975648Ssetje else drop then ( arg$ ) 4985648Ssetje endof 4995648Ssetje ascii H of 5005648Ssetje true to halt? 5015648Ssetje endof 5026423Sgw25295 ascii L of 5036423Sgw25295 " /" fs-name swap move 5046423Sgw25295 true to zflag? 5056423Sgw25295 " bootlst" boot-file swap move 5066423Sgw25295 true to fflag? 5076423Sgw25295 true to lflag? 5086423Sgw25295 endof 5095648Ssetje ascii Z of 5105648Ssetje skip-blanks next-str ( arg$ fs-name$ ) 5115648Ssetje ?dup if 5125648Ssetje fs-name swap move ( arg$ ) 5135648Ssetje true to zflag? 5145648Ssetje else drop then ( arg$ ) 5155648Ssetje endof 5165648Ssetje endcase 5175648Ssetje then 5185648Ssetje repeat 5195648Ssetje 2drop ( ) 5205648Ssetje; 5215648Ssetje 5225648Ssetje 5235648Ssetje0 value rd-alloc-sz 5245648Ssetje 5255648Ssetje: "ramdisk" ( -- dev$ ) " /ramdisk-root" ; 5265648Ssetje 5275648Ssetje: setup-bootprops ( -- ) 5285648Ssetje chosen-ph push-package 5295648Ssetje 5305648Ssetje nested? invert if 5315648Ssetje fs-type$ encode-string " fstype" property 5325648Ssetje fs-ih encode-int " bootfs" property 5335648Ssetje fs-bootprop if property then 5345648Ssetje else 5355648Ssetje fs-type$ encode-string " archive-fstype" property 5365648Ssetje fs-ih encode-int " archfs" property 5375648Ssetje then 5385648Ssetje 5395648Ssetje is-archive? if 5405648Ssetje "ramdisk" encode-string " bootarchive" property 5415648Ssetje else 5425648Ssetje loader-base encode-int " elfheader-address" property 5435648Ssetje file-sz encode-int " elfheader-length" property 5445648Ssetje plat-name$ encode-string " impl-arch-name" property 5455648Ssetje targ-file$ encode-string " whoami" property 5465648Ssetje fs-pkg$ encode-string " fs-package" property 5475648Ssetje then 5485648Ssetje 5495648Ssetje pop-package 5505648Ssetje; 5515648Ssetje 5525648Ssetje 5535648Ssetje\ load ramdisk fcode and tell the driver where 5545648Ssetje\ we put the ramdisk data 5555648Ssetje: setup-ramdisk ( base size -- ) 5565648Ssetje /rd-fcode mem-alloc ( base size adr ) 5575648Ssetje dup /rd-fcode fs-getrd 5585648Ssetje 5595648Ssetje root-ph push-package 5605648Ssetje new-device 5615648Ssetje "ramdisk" str++ device-name 5625648Ssetje dup 1 byte-load 5635648Ssetje finish-device 5645648Ssetje pop-package 5655648Ssetje 5665648Ssetje /rd-fcode mem-free ( base size ) 5675648Ssetje 5685648Ssetje "ramdisk" dev-open dup 0= if 5695648Ssetje "ramdisk" open-abort 5705648Ssetje then >r ( base size r: ih ) 5715648Ssetje rd-alloc-sz ( base size alloc-sz r: ih ) 5725648Ssetje " create" r@ $call-method ( r: ih ) 5735648Ssetje r> dev-close ( ) 5745648Ssetje; 5755648Ssetje 5765648Ssetje 5775648Ssetje\ 5785648Ssetje\ ELF parsing 5795648Ssetje\ 5805648Ssetje 5815726Sjgjheaderless 5825648Ssetje0 value elfhdr 5835648Ssetje0 value phdr 5845648Ssetje 5855648Ssetje: +elfhdr ( index -- value ) elfhdr swap ca+ ; 5865648Ssetje: e_machine ( -- n ) h# 12 +elfhdr w@ ; 5875648Ssetje: e_entry ( -- n ) h# 18 +elfhdr x@ ; 5885648Ssetje: e_phoff ( -- n ) h# 20 +elfhdr x@ ; 5895648Ssetje: e_phentsize ( -- n ) h# 36 +elfhdr w@ ; 5905648Ssetje: e_phnum ( -- n ) h# 38 +elfhdr w@ ; 5915648Ssetje 5925648Ssetje1 constant pt_load 5935648Ssetje: +phdr ( index -- value ) phdr swap ca+ ; 5945648Ssetje: p_type ( -- n ) h# 0 +phdr l@ ; 5955648Ssetje: p_vaddr ( -- n ) h# 10 +phdr x@ ; 5965648Ssetje: p_memsz ( -- n ) h# 28 +phdr x@ ; 5975648Ssetje 5985648Ssetje: get-phdr ( filebase index -- phdr ) 5995648Ssetje e_phentsize * e_phoff + + ( phdr ) 6005648Ssetje; 6015648Ssetje 6025648Ssetje\ alloc 4MB pages for kernel text/data 6035648Ssetje: vmem-alloc-4mb ( size virt -- base ) 6045648Ssetje swap 4meg roundup swap 6055648Ssetje 4meg (mem-alloc) 6065648Ssetje; 6075648Ssetje 6085726Sjgjheaders 6095648Ssetje\ OBP doesn't allocate memory for elf 6105648Ssetje\ programs, it assumes they'll fit 6115648Ssetje\ under the default 10MB limit 6125648Ssetje: fix-elf-mem ( base -- ) 6135648Ssetje dup to elfhdr 6145648Ssetje e_machine d# 43 <> if drop exit then \ 64b only 6155648Ssetje 6165648Ssetje e_phnum 0 ?do 6175648Ssetje dup i get-phdr to phdr 6185648Ssetje p_type pt_load = p_vaddr h# a0.0000 > and if 6195648Ssetje \ allocate 4MB segs for text & data 6205648Ssetje p_vaddr 4meg 1- and if 6215648Ssetje p_memsz p_vaddr vmem-alloc drop 6225648Ssetje else 6235648Ssetje p_memsz p_vaddr vmem-alloc-4mb drop 6245648Ssetje then 6255648Ssetje then 6265648Ssetje loop drop ( ) 6275648Ssetje; 6285648Ssetje 6295648Ssetje 6305648Ssetje: load-file ( -- virt ) 6315648Ssetje get-arch 6325648Ssetje get-targ open-path ( fd ) 6335648Ssetje loader-base over get-file if ( fd alloc-sz virt size ) 6346423Sgw25295 " Boot load failed" die 6355648Ssetje then 6365648Ssetje to file-sz ( fd alloc-sz virt ) 6375648Ssetje swap to rd-alloc-sz ( fd virt ) 6385648Ssetje swap fs-close ( virt ) 6395648Ssetje; 6405648Ssetje 6415648Ssetje: setup-props ( virt -- virt ) 6425648Ssetje dup get-type 6435648Ssetje setup-bootprops 6445648Ssetje is-archive? if 6455648Ssetje dup file-sz setup-ramdisk 6465648Ssetje then 6475648Ssetje; 6485648Ssetje 6495648Ssetje: exec-file ( virt -- ) 6505648Ssetje is-elf? if 6515648Ssetje dup fix-elf-mem 6525648Ssetje then 6535648Ssetje is-archive? if >bootblk then ( virt' ) 6545648Ssetje " to load-base init-program" evaluate 6555648Ssetje; 6565648Ssetje 6575648Ssetje: do-boot ( -- ) 6585648Ssetje parse-bootargs 6595648Ssetje halt? if 6605648Ssetje ." Halted with -H flag. " cr 6615648Ssetje exit 6625648Ssetje then 6635648Ssetje get-bootdev 6645648Ssetje load-pkg 6655648Ssetje mount-root 6665648Ssetje zflag? nested? invert and if 6675648Ssetje fs-name$ open-zfs-fs 6685648Ssetje then 6695648Ssetje load-file ( virt ) 6705648Ssetje setup-props 6715648Ssetje exec-file ( ) 6725648Ssetje; 6735648Ssetje 6745648Ssetje\ Tadpole proms don't initialize my-self 6755648Ssetje0 to my-self 6765648Ssetje 6775648Ssetjedo-boot 678