1986fd29aSsetje\ 2986fd29aSsetje\ CDDL HEADER START 3986fd29aSsetje\ 4986fd29aSsetje\ The contents of this file are subject to the terms of the 5986fd29aSsetje\ Common Development and Distribution License (the "License"). 6986fd29aSsetje\ You may not use this file except in compliance with the License. 7986fd29aSsetje\ 8986fd29aSsetje\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9986fd29aSsetje\ or http://www.opensolaris.org/os/licensing. 10986fd29aSsetje\ See the License for the specific language governing permissions 11986fd29aSsetje\ and limitations under the License. 12986fd29aSsetje\ 13986fd29aSsetje\ When distributing Covered Code, include this CDDL HEADER in each 14986fd29aSsetje\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15986fd29aSsetje\ If applicable, add the following below this CDDL HEADER, with the 16986fd29aSsetje\ fields enclosed by brackets "[]" replaced with your own identifying 17986fd29aSsetje\ information: Portions Copyright [yyyy] [name of copyright owner] 18986fd29aSsetje\ 19986fd29aSsetje\ CDDL HEADER END 20986fd29aSsetje\ 21986fd29aSsetje\ 22*c713350eSJohn Johnson\ Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23986fd29aSsetje\ Use is subject to license terms. 24986fd29aSsetje\ 25986fd29aSsetje 26986fd29aSsetjepurpose: boot block for OBP systems 27*c713350eSJohn Johnsoncopyright: Copyright 2009 Sun Microsystems, Inc. All Rights Reserved 28986fd29aSsetje 29986fd29aSsetje 30986fd29aSsetjeheaderless 31986fd29aSsetjed# 1024 dup * constant 1meg 32986fd29aSsetjed# 4 1meg * constant 4meg 33986fd29aSsetjed# 32 1meg * constant 32meg 34986fd29aSsetje 35986fd29aSsetjeheaders 36986fd29aSsetje" /" get-package constant root-ph 37986fd29aSsetje 38986fd29aSsetje0 value fs-ih 39986fd29aSsetjefalse value nested? 40986fd29aSsetje0 value file-sz 41986fd29aSsetje 42986fd29aSsetje/buf-len buffer: boot-dev 43986fd29aSsetje: boot-dev$ ( -- dev$ ) boot-dev cscount ; 44986fd29aSsetje 45986fd29aSsetje: loader-base ( -- base ) 46986fd29aSsetje nested? if 47986fd29aSsetje h# 5000.0000 48986fd29aSsetje else 49986fd29aSsetje h# 5100.0000 50986fd29aSsetje then 51986fd29aSsetje; 52986fd29aSsetje 53986fd29aSsetje 54986fd29aSsetje\ 55986fd29aSsetje\ methods we expect of fs reader packages 56986fd29aSsetje\ 57986fd29aSsetjeheaderless 58986fd29aSsetje: fs-open ( file$ -- fd true | false ) 59986fd29aSsetje " open-file" fs-ih $call-method 60986fd29aSsetje; 61986fd29aSsetje 62986fd29aSsetje: fs-close ( fd -- ) 63986fd29aSsetje " close-file" fs-ih $call-method 64986fd29aSsetje; 65986fd29aSsetje 66986fd29aSsetje: fs-size ( fd -- size ) 67986fd29aSsetje " size-file" fs-ih $call-method 68986fd29aSsetje; 69986fd29aSsetje 70986fd29aSsetje: fs-read ( adr len fd -- #read ) 71986fd29aSsetje " read-file" fs-ih $call-method 72986fd29aSsetje; 73986fd29aSsetje 74986fd29aSsetje: fs-getrd ( adr len -- ) 75986fd29aSsetje " get-rd" fs-ih $call-method 76986fd29aSsetje; 77986fd29aSsetje 78986fd29aSsetje: fs-bootprop ( -- propval propname true | false ) 79986fd29aSsetje " bootprop" fs-ih $call-method 80986fd29aSsetje; 81986fd29aSsetjeheaders 82986fd29aSsetje 83986fd29aSsetje 84629270abSjgj: check-elf ( base -- is-elf? ) 85629270abSjgj l@ h# 7f454c46 ( \x7fELF ) = 86629270abSjgj; 87629270abSjgj 88629270abSjgj: check-fcode ( base -- is-fcode? ) 89629270abSjgj c@ dup h# f0 h# f3 between swap h# fd = or 90629270abSjgj; 91629270abSjgj 92629270abSjgj 93986fd29aSsetje\ zfs bootblks with all headers exceeds 7.5k 94986fd29aSsetje\ 'bigbootblk' allows us to load the fs reader from elsewhere 95986fd29aSsetje[ifdef] bigbootblk 96986fd29aSsetje 97986fd29aSsetje: load-pkg ( -- ) 98629270abSjgj boot-dev$ ( dev$ ) 99629270abSjgj 2dup dev-open ?dup 0= if 100986fd29aSsetje open-abort 101986fd29aSsetje then >r 2drop ( r: ih ) 102629270abSjgj 103986fd29aSsetje /fs-fcode mem-alloc ( adr r: ih ) 104986fd29aSsetje dup /fs-fcode fs-offset r@ read-disk 105629270abSjgj 106629270abSjgj dup check-fcode invert if 107629270abSjgj " No fs fcode found" die 108629270abSjgj then 109986fd29aSsetje dup 1 byte-load 110629270abSjgj 111986fd29aSsetje /fs-fcode mem-free ( r: ih ) 112986fd29aSsetje r> dev-close 113986fd29aSsetje; 114986fd29aSsetje 115986fd29aSsetje[else] 116986fd29aSsetje 117986fd29aSsetje: load-pkg ( -- ) ; 118986fd29aSsetje 119986fd29aSsetje[then] 120986fd29aSsetje 121986fd29aSsetje 122986fd29aSsetje: get-bootdev ( -- ) 123986fd29aSsetje \ first try boot archive (nested boot from ramdisk) 124986fd29aSsetje \ then try boot device (direct boot from disk) 125986fd29aSsetje " bootarchive" chosen-ph get-package-property if 126986fd29aSsetje " bootpath" chosen-ph get-string-prop ( bootpath$ ) 127986fd29aSsetje else ( archiveprop$ ) 128986fd29aSsetje decode-string 2swap 2drop ( archivepath$ ) 129986fd29aSsetje true to nested? 130986fd29aSsetje then ( bootpath$ ) 131986fd29aSsetje boot-dev swap move ( ) 132986fd29aSsetje; 133986fd29aSsetje 134986fd29aSsetje: mount-root ( -- ) 135986fd29aSsetje boot-dev$ fs-pkg$ $open-package to fs-ih 136986fd29aSsetje fs-ih 0= if 137e7cbe64fSgw25295 " Can't mount root" die 138986fd29aSsetje then 139986fd29aSsetje; 140986fd29aSsetje 141986fd29aSsetje\ 142986fd29aSsetje\ cheap entertainment for those watching 143986fd29aSsetje\ boot progress 144986fd29aSsetje\ 145986fd29aSsetjeheaderless 146986fd29aSsetjecreate spin-data 147986fd29aSsetje ascii | c, ascii / c, ascii - c, ascii \ c, 148986fd29aSsetje 149*c713350eSJohn Johnsonvariable spindex 150986fd29aSsetje 151*c713350eSJohn Johnsonheaders 152986fd29aSsetje: spinner ( -- ) 153986fd29aSsetje spindex @ 3 and spin-data + ( c-adr ) 154986fd29aSsetje c@ emit (cr 155986fd29aSsetje 1 spindex +! 156986fd29aSsetje; 157986fd29aSsetje 158986fd29aSsetje\ allocate and return physical allocation size 159986fd29aSsetje: vmem-alloc-prop ( size virt -- alloc-size virt ) 160986fd29aSsetje 2dup ['] vmem-alloc catch if ( size virt ??? ??? ) 161986fd29aSsetje 2drop ( size virt ) 162986fd29aSsetje 2dup begin ( size virt len adr ) 163986fd29aSsetje over 32meg min >r ( size virt len adr r: alloc-sz ) 164986fd29aSsetje r@ over vmem-alloc ( size virt len adr adr r: alloc-sz ) 165986fd29aSsetje nip r@ + ( size virt len adr' r: alloc-sz ) 166986fd29aSsetje swap r> - ( size virt adr len' ) 167b8b2ae86Sjgj swap over 0= ( size virt len' adr done? ) 168b8b2ae86Sjgj until ( size virt len' adr ) 169986fd29aSsetje 2drop nip 32meg ( virt 32meg ) 170986fd29aSsetje else ( size virt virt ) 171986fd29aSsetje nip nip 0 ( virt 0 ) 172986fd29aSsetje then ( virt alloc-sz ) 173986fd29aSsetje swap 174986fd29aSsetje; 175986fd29aSsetje 176*c713350eSJohn Johnson\ read file in chunks so we can toggle the spinner 177*c713350eSJohn Johnson: read-file ( virt size fd -- failed? ) 178*c713350eSJohn Johnson >r ( virt sz-left r: fd ) 179*c713350eSJohn Johnson begin dup while 180*c713350eSJohn Johnson spinner 181*c713350eSJohn Johnson dup 4meg min ( virt sz-left read-sz r: fd ) 182*c713350eSJohn Johnson 3dup nip r@ fs-read ( virt sz-left read-sz size-read r: fd ) 183*c713350eSJohn Johnson over <> if ( virt sz-left read-sz r: fd ) 184*c713350eSJohn Johnson r> 2drop 2drop ( ) 185*c713350eSJohn Johnson true exit ( failed ) 186*c713350eSJohn Johnson then 187*c713350eSJohn Johnson rot over + ( sz-left read-sz virt' r: fd ) 188*c713350eSJohn Johnson -rot - ( virt' sz-left' r: fd ) 189*c713350eSJohn Johnson repeat 190*c713350eSJohn Johnson r> 3drop ( ) 191*c713350eSJohn Johnson false ( succeeded ) 192*c713350eSJohn Johnson; 193*c713350eSJohn Johnson 194986fd29aSsetje\ read in file and return buffer 195986fd29aSsetje\ if base==0, vmem-alloc will allocate virt 196b8b2ae86Sjgj\ NB returned size is 8k rounded since the 197b8b2ae86Sjgj\ memory allocator rounded it for us 198b8b2ae86Sjgj: get-file ( base fd -- [ alloc-sz virt size ] failed? ) 199986fd29aSsetje dup >r fs-size ( base size r: fd ) 200986fd29aSsetje dup rot vmem-alloc-prop ( size alloc-sz virt r: fd ) 201*c713350eSJohn Johnson rot 2dup ( alloc-sz virt size virt size r: fd ) 202*c713350eSJohn Johnson r> read-file if ( alloc-sz virt size ) 203986fd29aSsetje 3drop true exit ( failed ) 204986fd29aSsetje then 205b8b2ae86Sjgj h# 2000 roundup ( alloc-sz virt size' ) 206b8b2ae86Sjgj false ( alloc-sz virt size' succeeded ) 207986fd29aSsetje; 208986fd29aSsetje 209986fd29aSsetje 210986fd29aSsetjefalse value is-elf? 211986fd29aSsetjefalse value is-archive? 212986fd29aSsetje 213986fd29aSsetje 214986fd29aSsetje: >bootblk ( adr -- adr' ) d# 512 + ; 215986fd29aSsetje 216986fd29aSsetje\ figure out what we just loaded 217986fd29aSsetje: get-type ( adr -- ) 218986fd29aSsetje dup check-elf to is-elf? 219986fd29aSsetje 220986fd29aSsetje \ if not nested, check for boot archive (executable after label) 221986fd29aSsetje nested? invert if 222986fd29aSsetje >bootblk 223986fd29aSsetje dup check-fcode ( adr is-fcode? ) 224986fd29aSsetje over check-elf ( adr is-fcode? is-elf? ) 225986fd29aSsetje or to is-archive? 226986fd29aSsetje then 227986fd29aSsetje drop 228986fd29aSsetje; 229986fd29aSsetje 230986fd29aSsetje 231986fd29aSsetje\ 232986fd29aSsetje\ file name routines 233986fd29aSsetje\ 234986fd29aSsetje 235986fd29aSsetje\ boot file (-F name or boot archive) 236986fd29aSsetjefalse value fflag? 237986fd29aSsetje/buf-len buffer: boot-file 238986fd29aSsetje: boot-file$ ( -- file$ ) boot-file cscount ; 239986fd29aSsetje 240986fd29aSsetje\ kernel name (final name or unix) 241986fd29aSsetjefalse value kern? 242986fd29aSsetje/buf-len buffer: kern-file 243986fd29aSsetje: kern-file$ ( -- file$ ) kern-file cscount ; 244986fd29aSsetje 245986fd29aSsetje\ platform name 246986fd29aSsetje/buf-len buffer: plat-name 247986fd29aSsetje: plat-name$ ( -- plat$ ) plat-name cscount ; 248986fd29aSsetje 249986fd29aSsetje\ arch name 250986fd29aSsetje/buf-len buffer: arch-name 251986fd29aSsetje: arch-name$ ( -- arch$ ) arch-name cscount ; 252986fd29aSsetje 253986fd29aSsetje\ final name after /platform massaging 254986fd29aSsetje/buf-len buffer: targ-file 255986fd29aSsetje: targ-file$ ( -- file$ ) targ-file cscount ; 256986fd29aSsetje 257986fd29aSsetje: init-targ ( -- ) 258986fd29aSsetje targ-file /buf-len erase 259986fd29aSsetje " /platform/" targ-file swap move 260986fd29aSsetje; 261986fd29aSsetje 262986fd29aSsetje\ remove illegal file name chars (e.g., '/') 263986fd29aSsetje: munge-name ( name$ -- name$' ) 264986fd29aSsetje 2dup ( name$ name$ ) 265986fd29aSsetje begin dup while 266986fd29aSsetje over c@ ascii / = if 267986fd29aSsetje over ascii _ swap c! ( name$ name$' ) 268986fd29aSsetje then str++ 269986fd29aSsetje repeat 2drop ( name$ ) 270986fd29aSsetje; 271986fd29aSsetje 272296a4115Sjgj\ does /platform/<name> exist? 273296a4115Sjgj: try-platname ( name$ -- name$ true | false ) 274296a4115Sjgj munge-name ( name$' ) 275296a4115Sjgj init-targ 2dup targ-file$ $append 276296a4115Sjgj targ-file$ fs-open if ( name$ fd ) 277296a4115Sjgj fs-close true ( name$ true ) 278296a4115Sjgj else ( name$ ) 279296a4115Sjgj 2drop false ( false ) 280296a4115Sjgj then ( name$ true | false ) 281296a4115Sjgj; 282296a4115Sjgj 283296a4115Sjgj\ setup arch-name 284296a4115Sjgj\ sun4v -or- sun4u 285296a4115Sjgj: get-def-arch ( -- ) 286986fd29aSsetje " device_type" root-ph get-package-property if 287986fd29aSsetje \ some older sunfires don't have device_type set 288986fd29aSsetje false ( sun4u ) 289986fd29aSsetje else ( devtype-prop$ ) 290986fd29aSsetje decode-string 2swap 2drop ( devtype$ ) 291986fd29aSsetje " sun4v" $= ( sun4v? ) 292986fd29aSsetje then ( sun4v? ) 293986fd29aSsetje if " sun4v" else " sun4u" then ( arch$ ) 294986fd29aSsetje arch-name swap move 295296a4115Sjgj; 296296a4115Sjgj 297296a4115Sjgj\ setup plat-name 298296a4115Sjgj\ platform name -or- 299296a4115Sjgj\ compatible name -or- 300296a4115Sjgj\ default name 301296a4115Sjgj: get-arch ( -- ) 302296a4115Sjgj get-def-arch 303296a4115Sjgj 304296a4115Sjgj \ first try "name" in root 305986fd29aSsetje " name" root-ph get-string-prop ( name$ ) 306296a4115Sjgj try-platname if 307296a4115Sjgj plat-name swap move exit ( ) 308296a4115Sjgj then ( ) 309296a4115Sjgj 310296a4115Sjgj \ next try "compatible" 311296a4115Sjgj " compatible" root-ph ( prop$ ph ) 312296a4115Sjgj get-package-property invert if ( compat$ ) 313296a4115Sjgj begin decode-string dup while ( compat$ name$ ) 314296a4115Sjgj try-platname if 315296a4115Sjgj plat-name swap move 2drop exit ( ) 316296a4115Sjgj then ( compat$ ) 317296a4115Sjgj repeat 2drop 2drop ( ) 318296a4115Sjgj then ( ) 319296a4115Sjgj 320296a4115Sjgj \ else use default name 321296a4115Sjgj arch-name$ plat-name swap move 322986fd29aSsetje; 323986fd29aSsetje 324986fd29aSsetje\ make <pre> <file> into /platform/<pre>/<file> 325986fd29aSsetje: $plat-prepend ( file$ pre$ -- file$' ) 326986fd29aSsetje init-targ 327986fd29aSsetje targ-file$ $append ( file$ ) 328986fd29aSsetje " /" targ-file$ $append 329986fd29aSsetje targ-file$ $append ( ) 330986fd29aSsetje targ-file$ ( new$ ) 331986fd29aSsetje; 332986fd29aSsetje 333986fd29aSsetje: get-boot ( -- file$ ) 334986fd29aSsetje fflag? if 335986fd29aSsetje boot-file$ 336986fd29aSsetje else 337986fd29aSsetje " boot_archive" 338986fd29aSsetje then 339986fd29aSsetje; 340986fd29aSsetje 341986fd29aSsetje: get-kern ( -- file$ ) 342986fd29aSsetje kern? if 343986fd29aSsetje kern-file$ 344986fd29aSsetje else 345986fd29aSsetje " kernel/sparcv9/unix" 346986fd29aSsetje then 347986fd29aSsetje; 348986fd29aSsetje 349986fd29aSsetje\ if we're nested, load the kernel, else load the bootarchive 350986fd29aSsetje: get-targ ( -- file$ ) 351986fd29aSsetje nested? if 352986fd29aSsetje get-kern 353986fd29aSsetje else 354986fd29aSsetje get-boot 355986fd29aSsetje then 356986fd29aSsetje; 357986fd29aSsetje 358986fd29aSsetje 359986fd29aSsetje: try-file ( file$ -- [ fd ] error? ) 360986fd29aSsetje diagnostic-mode? if 361986fd29aSsetje 2dup ." Loading: " type cr 362986fd29aSsetje then 363986fd29aSsetje fs-open invert ( fd false | true ) 364986fd29aSsetje; 365986fd29aSsetje 366986fd29aSsetje\ try "/platform/<plat-name>/<file>" e.g., SUNW,Sun-Blade-1000 367986fd29aSsetje\ then "/platform/<arch-name>/<file>" e.g., sun4u 368986fd29aSsetje: open-path ( file$ - fd ) 369986fd29aSsetje over c@ ascii / <> if 370986fd29aSsetje 2dup plat-name$ $plat-prepend ( file$ file$' ) 371986fd29aSsetje try-file if ( file$ ) 372986fd29aSsetje 2dup arch-name$ $plat-prepend ( file$ file$' ) 373986fd29aSsetje try-file if ( file$ ) 374986fd29aSsetje open-abort 375986fd29aSsetje then ( file$ fd ) 376986fd29aSsetje then ( file$ fd ) 377986fd29aSsetje else ( file$ ) 378986fd29aSsetje \ copy to targ-file for 'whoami' prop 379986fd29aSsetje targ-file /buf-len erase 380986fd29aSsetje 2dup targ-file swap move 381986fd29aSsetje 2dup try-file if ( file$ ) 382986fd29aSsetje open-abort 383986fd29aSsetje then ( file$ fd ) 384986fd29aSsetje then ( file$ fd ) 385986fd29aSsetje -rot 2drop ( fd ) 386986fd29aSsetje; 387986fd29aSsetje 388986fd29aSsetje 389e7cbe64fSgw25295false value lflag? 390e7cbe64fSgw25295 391986fd29aSsetje\ ZFS support 392986fd29aSsetje\ -Z fsname opens specified filesystem in disk pool 393986fd29aSsetje 394986fd29aSsetjefalse value zflag? 395986fd29aSsetje/buf-len buffer: fs-name 396986fd29aSsetje: fs-name$ ( -- fs$ ) fs-name cscount ; 397986fd29aSsetje 398986fd29aSsetje[ifdef] zfs 399986fd29aSsetje 400986fd29aSsetje: open-zfs-fs ( fs$ -- ) 401986fd29aSsetje 2dup " open-fs" fs-ih $call-method 0= if 402986fd29aSsetje open-abort 403986fd29aSsetje then 404986fd29aSsetje 2drop ( ) 405986fd29aSsetje; 406986fd29aSsetje 407986fd29aSsetje[else] 408986fd29aSsetje 409986fd29aSsetje: open-zfs-fs ( fs$ -- ) 410e7cbe64fSgw25295 \ ignore on -L 411e7cbe64fSgw25295 lflag? invert if 412e7cbe64fSgw25295 " -Z not supported on non-zfs root" die 413e7cbe64fSgw25295 then 414986fd29aSsetje; 415986fd29aSsetje 416986fd29aSsetje[then] 417986fd29aSsetje 418986fd29aSsetje 419986fd29aSsetje\ 420986fd29aSsetje\ arg parsing 421986fd29aSsetje\ 422986fd29aSsetje 423986fd29aSsetjeheaderless 424986fd29aSsetje: printable? ( n -- flag ) \ true if n is a printable ascii character 425986fd29aSsetje dup bl th 7f within swap th 80 th ff between or 426986fd29aSsetje; 427986fd29aSsetje: white-space? ( n -- flag ) \ true is n is non-printable? or a blank 428986fd29aSsetje dup printable? 0= swap bl = or 429986fd29aSsetje; 430986fd29aSsetje 431986fd29aSsetje: skip-blanks ( adr len -- adr' len' ) 432986fd29aSsetje begin dup while ( adr' len' ) 433986fd29aSsetje over c@ white-space? 0= if exit then 434986fd29aSsetje str++ 435986fd29aSsetje repeat 436986fd29aSsetje; 437986fd29aSsetje 438986fd29aSsetje: skip-non-blanks ( adr len -- adr' len' ) 439986fd29aSsetje begin dup while ( adr' len' ) 440986fd29aSsetje over c@ white-space? if exit then 441986fd29aSsetje str++ 442986fd29aSsetje repeat 443986fd29aSsetje; 444986fd29aSsetje 445986fd29aSsetjeheaders 446986fd29aSsetje\ left-parse-string w/ any white space as delimeter 447986fd29aSsetje: next-str ( adr len -- adr' len' s-adr s-len ) 448986fd29aSsetje 2dup skip-non-blanks ( s-adr len adr' len' ) 449986fd29aSsetje dup >r 2swap r> - ( adr' len' s-adr s-len ) 450986fd29aSsetje; 451986fd29aSsetje 452*c713350eSJohn Johnson\ next char or 0 if eol 453986fd29aSsetje: next-c ( adr len -- adr' len' c ) 454*c713350eSJohn Johnson dup if over c@ >r str++ r> else 0 then 455986fd29aSsetje; 456986fd29aSsetje 457986fd29aSsetjefalse value halt? 458986fd29aSsetje 459986fd29aSsetje: parse-bootargs ( -- ) 460986fd29aSsetje " bootargs" chosen-ph get-string-prop ( arg$ ) 461986fd29aSsetje 462986fd29aSsetje \ check for explicit kernel name 463986fd29aSsetje skip-blanks dup if 464986fd29aSsetje over c@ ascii - <> if 465986fd29aSsetje next-str ( arg$ kern$ ) 466986fd29aSsetje \ use default kernel if user specific a debugger 467986fd29aSsetje 2dup " kadb" $= >r ( arg$ kern$ r: kadb? ) 468986fd29aSsetje 2dup " kmdb" $= r> or ( arg$ kern$ debugger? ) 469986fd29aSsetje invert if ( arg$ kern$ ) 470986fd29aSsetje kern-file swap move ( arg$ ) 471986fd29aSsetje true to kern? 472986fd29aSsetje else 2drop then ( arg$ ) 473986fd29aSsetje then 474986fd29aSsetje then 475986fd29aSsetje 476986fd29aSsetje \ process args 477986fd29aSsetje begin 478986fd29aSsetje skip-blanks dup ( arg$ len ) 479986fd29aSsetje while 480986fd29aSsetje next-c ascii - = if 481986fd29aSsetje next-c case 482986fd29aSsetje ascii D of 483986fd29aSsetje \ for "boot kadb -D kernel.foo/unix" 484986fd29aSsetje skip-blanks next-str ( arg$ file$ ) 485986fd29aSsetje kern? invert if 486986fd29aSsetje ?dup if 487986fd29aSsetje kern-file swap move ( arg$ ) 488986fd29aSsetje true to kern? 489986fd29aSsetje else drop then ( arg$ ) 490986fd29aSsetje else 2drop then ( arg$ ) 491986fd29aSsetje endof 492986fd29aSsetje ascii F of 493986fd29aSsetje skip-blanks next-str ( arg$ file$ ) 494986fd29aSsetje ?dup if 495986fd29aSsetje boot-file swap move ( arg$ ) 496986fd29aSsetje true to fflag? 497986fd29aSsetje else drop then ( arg$ ) 498986fd29aSsetje endof 499986fd29aSsetje ascii H of 500986fd29aSsetje true to halt? 501986fd29aSsetje endof 502e7cbe64fSgw25295 ascii L of 503e7cbe64fSgw25295 " /" fs-name swap move 504e7cbe64fSgw25295 true to zflag? 505e7cbe64fSgw25295 " bootlst" boot-file swap move 506e7cbe64fSgw25295 true to fflag? 507e7cbe64fSgw25295 true to lflag? 508e7cbe64fSgw25295 endof 509986fd29aSsetje ascii Z of 510986fd29aSsetje skip-blanks next-str ( arg$ fs-name$ ) 511986fd29aSsetje ?dup if 512986fd29aSsetje fs-name swap move ( arg$ ) 513986fd29aSsetje true to zflag? 514986fd29aSsetje else drop then ( arg$ ) 515986fd29aSsetje endof 516986fd29aSsetje endcase 517986fd29aSsetje then 518986fd29aSsetje repeat 519986fd29aSsetje 2drop ( ) 520986fd29aSsetje; 521986fd29aSsetje 522986fd29aSsetje 523986fd29aSsetje0 value rd-alloc-sz 524986fd29aSsetje 525986fd29aSsetje: "ramdisk" ( -- dev$ ) " /ramdisk-root" ; 526986fd29aSsetje 527986fd29aSsetje: setup-bootprops ( -- ) 528986fd29aSsetje chosen-ph push-package 529986fd29aSsetje 530986fd29aSsetje nested? invert if 531986fd29aSsetje fs-type$ encode-string " fstype" property 532986fd29aSsetje fs-ih encode-int " bootfs" property 533986fd29aSsetje fs-bootprop if property then 534986fd29aSsetje else 535986fd29aSsetje fs-type$ encode-string " archive-fstype" property 536986fd29aSsetje fs-ih encode-int " archfs" property 537986fd29aSsetje then 538986fd29aSsetje 539986fd29aSsetje is-archive? if 540986fd29aSsetje "ramdisk" encode-string " bootarchive" property 541986fd29aSsetje else 542986fd29aSsetje loader-base encode-int " elfheader-address" property 543986fd29aSsetje file-sz encode-int " elfheader-length" property 544986fd29aSsetje plat-name$ encode-string " impl-arch-name" property 545986fd29aSsetje targ-file$ encode-string " whoami" property 546986fd29aSsetje fs-pkg$ encode-string " fs-package" property 547986fd29aSsetje then 548986fd29aSsetje 549986fd29aSsetje pop-package 550986fd29aSsetje; 551986fd29aSsetje 552986fd29aSsetje 553986fd29aSsetje\ load ramdisk fcode and tell the driver where 554986fd29aSsetje\ we put the ramdisk data 555986fd29aSsetje: setup-ramdisk ( base size -- ) 556986fd29aSsetje /rd-fcode mem-alloc ( base size adr ) 557986fd29aSsetje dup /rd-fcode fs-getrd 558986fd29aSsetje 559986fd29aSsetje root-ph push-package 560986fd29aSsetje new-device 561986fd29aSsetje "ramdisk" str++ device-name 562986fd29aSsetje dup 1 byte-load 563986fd29aSsetje finish-device 564986fd29aSsetje pop-package 565986fd29aSsetje 566986fd29aSsetje /rd-fcode mem-free ( base size ) 567986fd29aSsetje 568986fd29aSsetje "ramdisk" dev-open dup 0= if 569986fd29aSsetje "ramdisk" open-abort 570986fd29aSsetje then >r ( base size r: ih ) 571986fd29aSsetje rd-alloc-sz ( base size alloc-sz r: ih ) 572986fd29aSsetje " create" r@ $call-method ( r: ih ) 573986fd29aSsetje r> dev-close ( ) 574986fd29aSsetje; 575986fd29aSsetje 576986fd29aSsetje 577986fd29aSsetje\ 578986fd29aSsetje\ ELF parsing 579986fd29aSsetje\ 580986fd29aSsetje 581296a4115Sjgjheaderless 582986fd29aSsetje0 value elfhdr 583986fd29aSsetje0 value phdr 584986fd29aSsetje 585986fd29aSsetje: +elfhdr ( index -- value ) elfhdr swap ca+ ; 586986fd29aSsetje: e_machine ( -- n ) h# 12 +elfhdr w@ ; 587986fd29aSsetje: e_entry ( -- n ) h# 18 +elfhdr x@ ; 588986fd29aSsetje: e_phoff ( -- n ) h# 20 +elfhdr x@ ; 589986fd29aSsetje: e_phentsize ( -- n ) h# 36 +elfhdr w@ ; 590986fd29aSsetje: e_phnum ( -- n ) h# 38 +elfhdr w@ ; 591986fd29aSsetje 592986fd29aSsetje1 constant pt_load 593986fd29aSsetje: +phdr ( index -- value ) phdr swap ca+ ; 594986fd29aSsetje: p_type ( -- n ) h# 0 +phdr l@ ; 595986fd29aSsetje: p_vaddr ( -- n ) h# 10 +phdr x@ ; 596986fd29aSsetje: p_memsz ( -- n ) h# 28 +phdr x@ ; 597986fd29aSsetje 598986fd29aSsetje: get-phdr ( filebase index -- phdr ) 599986fd29aSsetje e_phentsize * e_phoff + + ( phdr ) 600986fd29aSsetje; 601986fd29aSsetje 602986fd29aSsetje\ alloc 4MB pages for kernel text/data 603986fd29aSsetje: vmem-alloc-4mb ( size virt -- base ) 604986fd29aSsetje swap 4meg roundup swap 605986fd29aSsetje 4meg (mem-alloc) 606986fd29aSsetje; 607986fd29aSsetje 608296a4115Sjgjheaders 609986fd29aSsetje\ OBP doesn't allocate memory for elf 610986fd29aSsetje\ programs, it assumes they'll fit 611986fd29aSsetje\ under the default 10MB limit 612986fd29aSsetje: fix-elf-mem ( base -- ) 613986fd29aSsetje dup to elfhdr 614986fd29aSsetje e_machine d# 43 <> if drop exit then \ 64b only 615986fd29aSsetje 616986fd29aSsetje e_phnum 0 ?do 617986fd29aSsetje dup i get-phdr to phdr 618986fd29aSsetje p_type pt_load = p_vaddr h# a0.0000 > and if 619986fd29aSsetje \ allocate 4MB segs for text & data 620986fd29aSsetje p_vaddr 4meg 1- and if 621986fd29aSsetje p_memsz p_vaddr vmem-alloc drop 622986fd29aSsetje else 623986fd29aSsetje p_memsz p_vaddr vmem-alloc-4mb drop 624986fd29aSsetje then 625986fd29aSsetje then 626986fd29aSsetje loop drop ( ) 627986fd29aSsetje; 628986fd29aSsetje 629986fd29aSsetje 630986fd29aSsetje: load-file ( -- virt ) 631986fd29aSsetje get-arch 632986fd29aSsetje get-targ open-path ( fd ) 633986fd29aSsetje loader-base over get-file if ( fd alloc-sz virt size ) 634e7cbe64fSgw25295 " Boot load failed" die 635986fd29aSsetje then 636986fd29aSsetje to file-sz ( fd alloc-sz virt ) 637986fd29aSsetje swap to rd-alloc-sz ( fd virt ) 638986fd29aSsetje swap fs-close ( virt ) 639986fd29aSsetje; 640986fd29aSsetje 641986fd29aSsetje: setup-props ( virt -- virt ) 642986fd29aSsetje dup get-type 643986fd29aSsetje setup-bootprops 644986fd29aSsetje is-archive? if 645986fd29aSsetje dup file-sz setup-ramdisk 646986fd29aSsetje then 647986fd29aSsetje; 648986fd29aSsetje 649986fd29aSsetje: exec-file ( virt -- ) 650986fd29aSsetje is-elf? if 651986fd29aSsetje dup fix-elf-mem 652986fd29aSsetje then 653986fd29aSsetje is-archive? if >bootblk then ( virt' ) 654986fd29aSsetje " to load-base init-program" evaluate 655986fd29aSsetje; 656986fd29aSsetje 657986fd29aSsetje: do-boot ( -- ) 658986fd29aSsetje parse-bootargs 659986fd29aSsetje halt? if 660986fd29aSsetje ." Halted with -H flag. " cr 661986fd29aSsetje exit 662986fd29aSsetje then 663986fd29aSsetje get-bootdev 664986fd29aSsetje load-pkg 665986fd29aSsetje mount-root 666986fd29aSsetje zflag? nested? invert and if 667986fd29aSsetje fs-name$ open-zfs-fs 668986fd29aSsetje then 669986fd29aSsetje load-file ( virt ) 670986fd29aSsetje setup-props 671986fd29aSsetje exec-file ( ) 672986fd29aSsetje; 673986fd29aSsetje 674986fd29aSsetje\ Tadpole proms don't initialize my-self 675986fd29aSsetje0 to my-self 676986fd29aSsetje 677986fd29aSsetjedo-boot 678