xref: /titanic_51/usr/src/psm/stand/bootblks/common/boot.fth (revision c713350eb0c205161e2a4ab06cd996300721ac78)
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