These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / SLOF / slof / fs / packages / disk-label.fs
1 \ *****************************************************************************
2 \ * Copyright (c) 2004, 2008 IBM Corporation
3 \ * All rights reserved.
4 \ * This program and the accompanying materials
5 \ * are made available under the terms of the BSD License
6 \ * which accompanies this distribution, and is available at
7 \ * http://www.opensource.org/licenses/bsd-license.php
8 \ *
9 \ * Contributors:
10 \ *     IBM Corporation - initial implementation
11 \ ****************************************************************************/
12
13
14 \ Set debug-disk-label? to true to get debug messages for the disk-label code.
15 false VALUE debug-disk-label?
16
17 \ This value defines the maximum number of blocks (512b) to load from a PREP
18 \ partition. This is required to keep the load time in reasonable limits if the
19 \ PREP partition becomes big.
20 \ If we ever want to put a large kernel with initramfs from a PREP partition
21 \ we might need to increase this value. The default value is 65536 blocks (32MB)
22 d# 65536 value max-prep-partition-blocks
23 d# 4096 CONSTANT block-array-size
24
25 s" disk-label" device-name
26
27 0 INSTANCE VALUE partition
28 0 INSTANCE VALUE part-offset
29 0 INSTANCE VALUE disk-chrp-boot
30
31 0 INSTANCE VALUE part-start
32 0 INSTANCE VALUE lpart-start
33 0 INSTANCE VALUE part-size
34 0 INSTANCE VALUE dos-logical-partitions
35
36 0 INSTANCE VALUE block-size
37 0 INSTANCE VALUE block
38
39 0 INSTANCE VALUE args
40 0 INSTANCE VALUE args-len
41
42 0 INSTANCE VALUE gpt-part-size
43 0 INSTANCE VALUE seek-pos
44
45
46 INSTANCE VARIABLE block#  \ variable to store logical sector#
47 INSTANCE VARIABLE hit#    \ partition counter
48 INSTANCE VARIABLE success-flag
49
50 \ ISO9660 specific information
51 0ff constant END-OF-DESC
52 3 constant  PARTITION-ID
53 48 constant VOL-PART-LOC
54
55
56 \ DOS partition label (MBR) specific structures
57
58 STRUCT
59        1b8 field mbr>boot-loader
60         /l field mbr>disk-signature
61         /w field mbr>null
62         40 field mbr>partition-table
63         /w field mbr>magic
64
65 CONSTANT /mbr
66
67 STRUCT
68         /c field part-entry>active
69         /c field part-entry>start-head
70         /c field part-entry>start-sect
71         /c field part-entry>start-cyl
72         /c field part-entry>id
73         /c field part-entry>end-head
74         /c field part-entry>end-sect
75         /c field part-entry>end-cyl
76         /l field part-entry>sector-offset
77         /l field part-entry>sector-count
78
79 CONSTANT /partition-entry
80
81 STRUCT
82         8 field gpt>signature
83         4 field gpt>revision
84         4 field gpt>header-size
85         4 field gpt>header-crc32
86         4 field gpt>reserved
87         8 field gpt>current-lba
88         8 field gpt>backup-lba
89         8 field gpt>first-lba
90         8 field gpt>last-lba
91        10 field gpt>disk-guid
92         8 field gpt>part-entry-lba
93         4 field gpt>num-part-entry
94         4 field gpt>part-entry-size
95         4 field gpt>part-array-crc32
96       1a4 field gpt>reserved
97
98 CONSTANT /gpt-header
99
100 STRUCT
101        10 field gpt-part-entry>part-type-guid
102        10 field gpt-part-entry>part-guid
103         8 field gpt-part-entry>first-lba
104         8 field gpt-part-entry>last-lba
105         8 field gpt-part-entry>attribute
106        48 field gpt-part-entry>part-name
107
108 CONSTANT /gpt-part-entry
109
110 \ Defined by IEEE 1275-1994 (3.8.1)
111
112 : offset ( d.rel -- d.abs )
113    part-offset xlsplit d+
114 ;
115
116 : seek  ( pos.lo pos.hi -- status )
117    offset
118    debug-disk-label? IF 2dup ." seek-parent: pos.hi=0x" u. ." pos.lo=0x" u. THEN
119    s" seek" $call-parent
120    debug-disk-label? IF dup ." status=" . cr THEN
121 ;
122
123 : read ( addr len -- actual )
124    debug-disk-label? IF 2dup swap ." read-parent: addr=0x" u. ." len=" .d THEN
125    s" read" $call-parent
126    debug-disk-label? IF dup ." actual=" .d cr THEN
127 ;
128
129
130 \ read sector to array "block"
131 : read-sector ( sector-number -- )
132    \ block-size is 0x200 on disks, 0x800 on cdrom drives
133    block-size * 0 seek drop      \ seek to sector
134    block block-size read drop    \ read sector
135 ;
136
137 : (.part-entry) ( part-entry )
138    cr ." part-entry>active:        " dup part-entry>active c@ .d
139    cr ." part-entry>start-head:    " dup part-entry>start-head c@ .d
140    cr ." part-entry>start-sect:    " dup part-entry>start-sect c@ .d
141    cr ." part-entry>start-cyl:     " dup part-entry>start-cyl  c@ .d
142    cr ." part-entry>id:            " dup part-entry>id c@ .d
143    cr ." part-entry>end-head:      " dup part-entry>end-head c@ .d
144    cr ." part-entry>end-sect:      " dup part-entry>end-sect c@ .d
145    cr ." part-entry>end-cyl:       " dup part-entry>end-cyl c@ .d
146    cr ." part-entry>sector-offset: " dup part-entry>sector-offset l@-le .d
147    cr ." part-entry>sector-count:  " dup part-entry>sector-count l@-le .d
148    cr
149 ;
150
151 : (.name) r@ begin cell - dup @ <colon> = UNTIL xt>name cr type space ;
152
153 : init-block ( -- )
154    s" block-size" ['] $call-parent CATCH IF ABORT" parent has no block-size." THEN
155    to block-size
156    block-array-size alloc-mem
157    dup block-array-size erase
158    to block
159    debug-disk-label? IF
160       ." init-block: block-size=" block-size .d ." block=0x" block u. cr
161    THEN
162 ;
163
164 : partition>part-entry ( partition -- part-entry )
165    1- /partition-entry * block mbr>partition-table +
166 ;
167
168 : partition>start-sector ( partition -- sector-offset )
169    partition>part-entry part-entry>sector-offset l@-le
170 ;
171
172 \ This word returns true if the currently loaded block has _NO_ MBR magic
173 : no-mbr? ( -- true|false )
174    0 read-sector
175    1 partition>part-entry part-entry>id c@ ee = IF TRUE EXIT THEN \ GPT partition found
176    block mbr>magic w@-le aa55 <>
177 ;
178
179 \ This word returns true if the currently loaded block has _NO_ GPT partition id
180 : no-gpt? ( -- true|false )
181    0 read-sector
182    1 partition>part-entry part-entry>id c@ ee <> IF true EXIT THEN
183    block mbr>magic w@-le aa55 <>
184 ;
185
186 : pc-extended-partition? ( part-entry-addr -- true|false )
187    part-entry>id c@      ( id )
188    dup 5 = swap          ( true|false id )
189    dup f = swap          ( true|false true|false id )
190    85 =                  ( true|false true|false true|false )
191    or or                 ( true|false )
192 ;
193
194 : count-dos-logical-partitions ( -- #logical-partitions )
195    no-mbr? IF 0 EXIT THEN
196    0 5 1 DO                                ( current )
197       i partition>part-entry               ( current part-entry )
198       dup pc-extended-partition? IF
199          part-entry>sector-offset l@-le    ( current sector )
200          dup to part-start to lpart-start  ( current )
201          BEGIN
202             part-start read-sector          \ read EBR
203             1 partition>start-sector IF
204                \ ." Logical Partition found at " part-start .d cr
205                1+
206             THEN \ another logical partition
207             2 partition>start-sector
208             ( current relative-sector )
209             ?dup IF lpart-start + to part-start false ELSE true THEN
210          UNTIL
211       ELSE
212          drop
213       THEN
214    LOOP
215 ;
216
217 : (get-dos-partition-params) ( ext-part-start part-entry -- offset count active? id )
218    dup part-entry>sector-offset l@-le rot + swap ( offset part-entry )
219    dup part-entry>sector-count l@-le swap        ( offset count part-entry )
220    dup part-entry>active c@ 80 = swap            ( offset count active? part-entry )
221    part-entry>id c@                              ( offset count active? id )
222 ;
223
224 : find-dos-partition ( partition# -- false | offset count active? id true )
225    to partition 0 to part-start 0 to part-offset
226
227    \ no negative partitions
228    partition 0<= IF 0 to partition false EXIT THEN
229
230    \ load MBR and check it
231    no-mbr? IF 0 to partition false EXIT THEN
232
233    partition 4 <= IF \ Is this a primary partition?
234       0 partition partition>part-entry
235       (get-dos-partition-params)
236       \ FIXME sanity checks?
237       true EXIT
238    ELSE
239       partition 4 - 0 5 1 DO                      ( logical-partition current )
240          i partition>part-entry                   ( log-part current part-entry )
241          dup pc-extended-partition? IF
242             part-entry>sector-offset l@-le        ( log-part current sector )
243             dup to part-start to lpart-start      ( log-part current )
244             BEGIN
245                part-start read-sector             \ read EBR
246                1 partition>start-sector IF        \ first partition entry
247                   1+ 2dup = IF                    ( log-part current )
248                      2drop
249                      part-start 1 partition>part-entry
250                      (get-dos-partition-params)
251                      true UNLOOP EXIT
252                   THEN
253                   2 partition>start-sector
254                   ( log-part current relative-sector )
255
256                   ?dup IF lpart-start + to part-start false ELSE true THEN
257                ELSE
258                   true
259                THEN
260             UNTIL
261          ELSE
262             drop
263          THEN
264       LOOP
265       2drop false
266    THEN
267 ;
268
269 : try-dos-partition ( -- okay? )
270    \ Read partition table and check magic.
271    no-mbr? IF
272        debug-disk-label? IF cr ." No DOS disk-label found." cr THEN
273        false EXIT
274    THEN
275
276    count-dos-logical-partitions TO dos-logical-partitions
277
278    debug-disk-label? IF
279       ." Found " dos-logical-partitions .d ." logical partitions" cr
280       ." Partition = " partition .d cr
281    THEN
282
283    partition 1 5 dos-logical-partitions +
284    within 0= IF
285       cr ." Partition # not 1-" 4 dos-logical-partitions + . cr false EXIT
286    THEN
287
288    \ Could/should check for valid partition here...  the magic is not enough really.
289
290    \ Get the partition offset.
291
292    partition find-dos-partition IF
293      ( offset count active? id )
294      2drop
295      to part-size
296      block-size * to part-offset
297      true
298    ELSE
299      false
300    THEN
301 ;
302
303 \ Check for an ISO-9660 filesystem on the disk
304 \ : try-iso9660-partition ( -- true|false )
305 \ implement me if you can ;-)
306 \ ;
307
308
309 \ Check for an ISO-9660 filesystem on the disk
310 \ (cf. CHRP IEEE 1275 spec., chapter 11.1.2.3)
311 : has-iso9660-filesystem  ( -- TRUE|FALSE )
312    \ Seek to the beginning of logical 2048-byte sector 16
313    \ refer to Chapter C.11.1 in PAPR 2.0 Spec
314    \ was: 10 read-sector, but this might cause trouble if you
315    \ try booting an ISO image from a device with 512b sectors.
316    10 800 * 0 seek drop      \ seek to sector
317    block 800 read drop       \ read sector
318    \ Check for CD-ROM volume magic:
319    block c@ 1 =
320    block 1+ 5 s" CD001"  str=
321    and
322    dup IF 800 to block-size THEN
323 ;
324
325
326 \ Load from first active DOS boot partition.
327
328 : fat-bootblock? ( addr -- flag )
329    \ byte 0-2 of the bootblock is a jump instruction in
330    \ all FAT filesystems.
331    \ e9 and eb are jump instructions in x86 assembler.
332    dup c@ e9 = IF drop true EXIT THEN
333    dup c@ eb = swap 2+ c@ 90 = and
334 ;
335
336 \ NOTE: block-size is always 512 bytes for DOS partition tables.
337
338 : load-from-dos-boot-partition ( addr -- size )
339    no-mbr? IF drop FALSE EXIT THEN  \ read MBR and check for DOS disk-label magic
340
341    count-dos-logical-partitions TO dos-logical-partitions
342
343    debug-disk-label? IF
344       ." Found " dos-logical-partitions .d ." logical partitions" cr
345       ." Partition = " partition .d cr
346    THEN
347
348    \ Now walk through the partitions:
349    5 dos-logical-partitions + 1 DO
350       \ ." checking partition " i .
351       i find-dos-partition IF        ( addr offset count active? id )
352          41 = and                    ( addr offset count prep-boot-part? )
353          IF                          ( addr offset count )
354             max-prep-partition-blocks min  \ reduce load size
355             swap                     ( addr count offset )
356             block-size * to part-offset
357             0 0 seek drop            ( addr offset )
358             block-size * read        ( size )
359             UNLOOP EXIT
360          ELSE
361             2drop                    ( addr )
362          THEN
363       THEN
364    LOOP
365    drop 0
366 ;
367
368 \ Check for GPT PReP partition GUID. Only first 3 blocks are
369 \ byte-swapped treating last two blocks as contigous for simplifying
370 \ comparison
371 9E1A2D38            CONSTANT GPT-PREP-PARTITION-1
372 C612                CONSTANT GPT-PREP-PARTITION-2
373 4316                CONSTANT GPT-PREP-PARTITION-3
374 AA268B49521E5A8B    CONSTANT GPT-PREP-PARTITION-4
375
376 : gpt-prep-partition? ( -- true|false )
377    block gpt-part-entry>part-type-guid
378    dup l@-le     GPT-PREP-PARTITION-1 <> IF drop false EXIT THEN
379    dup 4 + w@-le GPT-PREP-PARTITION-2 <> IF drop false EXIT THEN
380    dup 6 + w@-le GPT-PREP-PARTITION-3 <> IF drop false EXIT THEN
381        8 + x@    GPT-PREP-PARTITION-4 =
382 ;
383
384 \ Check for GPT MSFT BASIC DATA GUID - fat based
385 EBD0A0A2            CONSTANT GPT-BASIC-DATA-PARTITION-1
386 B9E5                CONSTANT GPT-BASIC-DATA-PARTITION-2
387 4433                CONSTANT GPT-BASIC-DATA-PARTITION-3
388 87C068B6B72699C7    CONSTANT GPT-BASIC-DATA-PARTITION-4
389
390 : gpt-basic-data-partition? ( -- true|false )
391    block gpt-part-entry>part-type-guid
392    dup l@-le     GPT-BASIC-DATA-PARTITION-1 <> IF drop false EXIT THEN
393    dup 4 + w@-le GPT-BASIC-DATA-PARTITION-2 <> IF drop false EXIT THEN
394    dup 6 + w@-le GPT-BASIC-DATA-PARTITION-3 <> IF drop false EXIT THEN
395        8 + x@    GPT-BASIC-DATA-PARTITION-4 =
396 ;
397
398 \
399 \ GPT Signature
400 \ ("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h)
401 \
402 4546492050415254 CONSTANT GPT-SIGNATURE
403
404 \ The routine checks whether the protective MBR has GPT ID and then
405 \ reads the gpt data from the sector. Also set the seek position and
406 \ the partition size used in caller routines.
407
408 : get-gpt-partition ( -- true|false )
409    no-gpt? IF false EXIT THEN
410    debug-disk-label? IF cr ." GPT partition found " cr  THEN
411    1 read-sector
412    block gpt>part-entry-lba x@-le
413    block-size * to seek-pos
414    block gpt>part-entry-size l@-le to gpt-part-size
415    gpt-part-size block-array-size > IF
416       cr ." GPT part size exceeds buffer allocated " cr
417       false exit
418    THEN
419    block gpt>signature x@ GPT-SIGNATURE =
420 ;
421
422 : load-from-gpt-prep-partition ( addr -- size )
423    get-gpt-partition 0= IF false EXIT THEN
424    block gpt>num-part-entry l@-le dup 0= IF false exit THEN
425    1+ 1 ?DO
426       seek-pos 0 seek drop
427       block gpt-part-size read drop gpt-prep-partition? IF
428          debug-disk-label? IF  ." GPT PReP partition found " cr THEN
429          block gpt-part-entry>first-lba x@-le ( addr first-lba )
430          block gpt-part-entry>last-lba x@-le  ( addr first-lba last-lba)
431          over - 1+                            ( addr first-lba blocks )
432          swap                                 ( addr blocks first-lba )
433          block-size * to part-offset          ( addr blocks )
434          0 0 seek drop                        ( addr blocks )
435          block-size * read                    ( size )
436          UNLOOP EXIT
437      THEN
438      seek-pos gpt-part-size + to seek-pos
439    LOOP
440    false
441 ;
442
443 : try-gpt-dos-partition ( -- true|false )
444    get-gpt-partition 0= IF false EXIT THEN
445    block gpt>num-part-entry l@-le dup 0= IF false EXIT THEN
446    1+ 1 ?DO
447       seek-pos 0 seek drop
448       block gpt-part-size read drop
449       gpt-basic-data-partition? IF
450          debug-disk-label? IF ." GPT BASIC DATA partition found " cr THEN
451          block gpt-part-entry>first-lba x@-le       ( first-lba )
452          dup to part-start                          ( first-lba )
453          block gpt-part-entry>last-lba x@-le        ( first-lba last-lba )
454          over - 1+                                  ( first-lba s1 )
455          block-size * to part-size                  ( first-lba )
456          block-size * to part-offset                ( )
457          0 0 seek drop
458          block block-size read drop
459          block fat-bootblock?                    ( true|false )
460          UNLOOP EXIT
461       THEN
462       seek-pos gpt-part-size + to seek-pos
463    LOOP
464    false
465 ;
466
467 \ Extract the boot loader path from a bootinfo.txt file
468 \ In: address and length of buffer where the bootinfo.txt has been loaded to.
469 \ Out: string address and length of the boot loader (within the input buffer)
470 \      or a string with length = 0 when parsing failed.
471
472 \ Here is a sample bootinfo file:
473 \ <chrp-boot>
474 \   <description>Linux Distribution</description>
475 \   <os-name>Linux</os-name>
476 \   <boot-script>boot &device;:1,\boot\yaboot.ibm</boot-script>
477 \   <icon size=64,64 color-space=3,3,2>
478 \     <bitmap>[..]</bitmap>
479 \   </icon>
480 \ </chrp-boot>
481
482 : parse-bootinfo-txt  ( addr len -- str len )
483    2dup s" <boot-script>" find-substr       ( addr len pos1 )
484    2dup = IF
485       \ String not found
486       3drop 0 0 EXIT
487    THEN
488    dup >r - swap r> + swap                  ( addr1 len1 )
489
490    2dup s" &device;:" find-substr           ( addr1 len1 posdev )
491    2dup = IF
492       3drop 0 0 EXIT
493    THEN
494    9 +                                      \ Skip the "&device;:" string
495    dup >r - swap r> + swap                  ( addr2 len2 )
496    2dup s" </boot-script>" find-substr nip  ( addr2 len3 )
497
498    debug-disk-label? IF
499       ." Extracted boot loader from bootinfo.txt: '"
500       2dup type ." '" cr
501    THEN
502 ;
503
504 \ Try to load \ppc\bootinfo.txt from the disk (used mainly on CD-ROMs), and if
505 \ available, get the boot loader path from this file and load it.
506 \ See the "CHRP system binding to IEEE 1275" specification for more information
507 \ about bootinfo.txt. An example file can be found in the comment of
508 \ parse-bootinfo-txt ( addr len -- str len )
509
510 : load-chrp-boot-file ( addr -- size )
511    \ Create bootinfo.txt path name and load that file:
512    my-parent instance>path
513    disk-chrp-boot @ 1 = IF
514        s" :1,\ppc\bootinfo.txt" $cat strdup       ( addr str len )
515    ELSE
516        s" :\ppc\bootinfo.txt" $cat strdup       ( addr str len )
517    THEN
518    open-dev dup 0= IF 2drop 0 EXIT THEN
519    >r dup                                   ( addr addr R:ihandle )
520    dup s" load" r@ $call-method             ( addr addr size R:ihandle )
521    r> close-dev                             ( addr addr size )
522
523    \ Now parse the information from bootinfo.txt:
524    parse-bootinfo-txt                       ( addr fnstr fnlen )
525    dup 0= IF 3drop 0 EXIT THEN
526    \ Does the string contain parameters (i.e. a white space)?
527    2dup 20 findchar IF
528       ( addr fnstr fnlen offset )
529       >r 2dup r@ - 1- swap r@ + 1+ swap     ( addr fnstr fnlen pstr plen  R: offset )
530       encode-string s" bootargs" set-chosen
531       drop r>
532    THEN
533
534    \ Create the full path to the boot loader:
535    my-parent instance>path      ( addr fnstr fnlen nstr nlen )
536    s" :" $cat 2swap $cat strdup             ( addr str len )
537    \ Update the bootpath:
538    2dup encode-string s" bootpath" set-chosen
539    \ And finally load the boot loader itself:
540    open-dev dup 0= IF ." failed to load CHRP boot loader." 2drop 0 EXIT THEN
541    >r s" load" r@ $call-method              ( size R:ihandle )
542    r> close-dev                             ( size )
543 ;
544
545 \ load from a bootable partition
546 : load-from-boot-partition ( addr -- size )
547    debug-disk-label? IF ." Trying DOS boot " .s cr THEN
548    dup load-from-dos-boot-partition ?dup 0 <> IF nip EXIT THEN
549
550    debug-disk-label? IF ." Trying CHRP boot " .s cr THEN
551    1 disk-chrp-boot !
552    dup load-chrp-boot-file ?dup 0 <> IF nip EXIT THEN
553    0 disk-chrp-boot !
554
555    debug-disk-label? IF ." Trying GPT boot " .s cr THEN
556    load-from-gpt-prep-partition
557    \ More boot partition formats ...
558 ;
559
560 \ parse partition number from my-args
561
562 \ my-args has the following format
563 \ [<partition>[,<path>]]
564
565 \ | example my-args  | example boot command      |
566 \ +------------------+---------------------------+
567 \ | 1,\boot\vmlinuz  | boot disk:1,\boot\vmlinuz |
568 \ | 2                | boot disk:2               |
569
570 \ 0 means the whole disk, this is the same behavior
571 \ as if no partition is specified (yaboot wants this).
572
573 : parse-partition ( -- okay? )
574    0 to partition
575    0 to part-offset
576    0 to part-size
577
578    my-args to args-len to args
579
580    debug-disk-label? IF
581       cr ." disk-label parse-partition: my-args=" my-args type cr
582    THEN
583
584    \ Called without arguments?
585    args-len 0 = IF true EXIT THEN
586
587    \ Check for "full disk" arguments.
588    my-args [char] , findchar 0= IF \ no comma?
589       args c@ isdigit not IF       \ ... and not a partition number?
590          true EXIT                 \ ... then it's not a partition we can parse
591       THEN
592    ELSE
593       drop
594    THEN
595    my-args [char] , split to args-len to args
596    dup 0= IF 2drop true EXIT THEN \ no first argument
597
598    \ Check partition #.
599    base @ >r decimal $number r> base !
600    IF cr ." Not a partition #" false EXIT THEN
601
602    \ Store part #, done.
603    to partition
604    true
605 ;
606
607
608 \ try-files and try-partitions
609
610 : (interpose-filesystem) ( str len -- )
611    find-package IF args args-len rot interpose THEN
612 ;
613
614 : try-dos-files ( -- found? )
615    no-mbr? IF false EXIT THEN
616
617    block fat-bootblock? 0= IF false EXIT THEN
618    s" fat-files" (interpose-filesystem)
619    true
620 ;
621
622 : try-ext2-files ( -- found? )
623    2 read-sector               \ read first superblock
624    block d# 56 + w@-le         \ fetch s_magic
625    ef53 <> IF false EXIT THEN  \ s_magic found?
626    s" ext2-files" (interpose-filesystem)
627    true
628 ;
629
630
631 : try-iso9660-files
632    has-iso9660-filesystem 0= IF false exit THEN
633    s" iso-9660" (interpose-filesystem)
634    true
635 ;
636
637 : try-files ( -- found? )
638    \ If no path, then full disk.
639    args-len 0= IF true EXIT THEN
640
641    try-dos-files IF true EXIT THEN
642    try-ext2-files IF true EXIT THEN
643    try-iso9660-files IF true EXIT THEN
644
645    \ ... more filesystem types here ...
646
647    false
648 ;
649
650 : try-partitions ( -- found? )
651    try-dos-partition IF try-files EXIT THEN
652    try-gpt-dos-partition IF try-files EXIT THEN
653    \ try-iso9660-partition IF try-files EXIT THEN
654    \ ... more partition types here...
655    false
656 ;
657
658 \ Interface functions for disk-label package
659 \ as defined by IEEE 1275-1994 3.8.1
660
661 : close ( -- )
662    debug-disk-label? IF ." Closing disk-label: block=0x" block u. ." block-size=" block-size .d cr THEN
663    block block-array-size free-mem
664 ;
665
666
667 : open ( -- true|false )
668    init-block
669
670    parse-partition 0= IF
671       close
672       false EXIT
673    THEN
674
675    partition IF
676        try-partitions
677    ELSE
678        try-files
679    THEN
680    dup 0= IF debug-disk-label? IF ." not found." cr THEN close THEN \ free memory again
681 ;
682
683
684 \ Boot & Load w/o arguments is assumed to be boot from boot partition
685
686 : load ( addr -- size )
687    debug-disk-label? IF
688       ." load: " dup u. cr
689    THEN
690
691    args-len IF
692       TRUE ABORT" Load done w/o filesystem"
693    ELSE
694       partition IF
695          0 0 seek drop
696          part-size IF
697             part-size max-prep-partition-blocks min   \ Load size
698          ELSE
699             max-prep-partition-blocks
700          THEN
701          200 *  read
702       ELSE
703          has-iso9660-filesystem IF
704              dup load-chrp-boot-file ?dup 0 > IF nip EXIT THEN
705          THEN
706          load-from-boot-partition
707          dup 0= ABORT" No boot partition found"
708       THEN
709    THEN
710 ;