Annotation of qemu/roms/SLOF/slof/fs/packages/disk-label.fs, revision 1.1

1.1     ! root        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 16384 blocks (8MB)
        !            22: d# 16384 value max-prep-partition-blocks
        !            23: 
        !            24: s" disk-label" device-name
        !            25: 
        !            26: 0 INSTANCE VALUE partition
        !            27: 0 INSTANCE VALUE part-offset
        !            28: 
        !            29: 0 INSTANCE VALUE part-start
        !            30: 0 INSTANCE VALUE lpart-start
        !            31: 0 INSTANCE VALUE part-size
        !            32: 0 INSTANCE VALUE dos-logical-partitions
        !            33: 
        !            34: 0 INSTANCE VALUE block-size
        !            35: 0 INSTANCE VALUE block
        !            36: 
        !            37: 0 INSTANCE VALUE args
        !            38: 0 INSTANCE VALUE args-len
        !            39: 
        !            40: 
        !            41: INSTANCE VARIABLE block#  \ variable to store logical sector#
        !            42: INSTANCE VARIABLE hit#    \ partition counter
        !            43: INSTANCE VARIABLE success-flag
        !            44: 
        !            45: \ ISO9660 specific information
        !            46: 0ff constant END-OF-DESC
        !            47: 3 constant  PARTITION-ID
        !            48: 48 constant VOL-PART-LOC
        !            49: 
        !            50: 
        !            51: \ DOS partition label (MBR) specific structures
        !            52: 
        !            53: STRUCT
        !            54:        1b8 field mbr>boot-loader
        !            55:         /l field mbr>disk-signature
        !            56:         /w field mbr>null
        !            57:         40 field mbr>partition-table
        !            58:         /w field mbr>magic
        !            59: 
        !            60: CONSTANT /mbr
        !            61: 
        !            62: STRUCT
        !            63:         /c field part-entry>active
        !            64:         /c field part-entry>start-head
        !            65:         /c field part-entry>start-sect
        !            66:         /c field part-entry>start-cyl
        !            67:         /c field part-entry>id
        !            68:         /c field part-entry>end-head
        !            69:         /c field part-entry>end-sect
        !            70:         /c field part-entry>end-cyl
        !            71:         /l field part-entry>sector-offset
        !            72:         /l field part-entry>sector-count
        !            73: 
        !            74: CONSTANT /partition-entry
        !            75: 
        !            76: 
        !            77: \ Defined by IEEE 1275-1994 (3.8.1)
        !            78: 
        !            79: : offset ( d.rel -- d.abs )
        !            80:    part-offset 0 d+
        !            81: ;
        !            82: 
        !            83: : seek  ( pos.lo pos.hi -- status )
        !            84:    offset
        !            85:    debug-disk-label? IF 2dup ." seek-parent: pos.hi=0x" u. ." pos.lo=0x" u. THEN
        !            86:    s" seek" $call-parent
        !            87:    debug-disk-label? IF dup ." status=" . cr THEN
        !            88: ;
        !            89: 
        !            90: : read ( addr len -- actual )
        !            91:    debug-disk-label? IF 2dup swap ." read-parent: addr=0x" u. ." len=" .d THEN
        !            92:    s" read" $call-parent
        !            93:    debug-disk-label? IF dup ." actual=" .d cr THEN
        !            94: ;
        !            95: 
        !            96: 
        !            97: \ read sector to array "block"
        !            98: : read-sector ( sector-number -- )
        !            99:    \ block-size is 0x200 on disks, 0x800 on cdrom drives
        !           100:    block-size * 0 seek drop      \ seek to sector
        !           101:    block block-size read drop    \ read sector
        !           102: ;
        !           103: 
        !           104: : (.part-entry) ( part-entry )
        !           105:    cr ." part-entry>active:        " dup part-entry>active c@ .d
        !           106:    cr ." part-entry>start-head:    " dup part-entry>start-head c@ .d
        !           107:    cr ." part-entry>start-sect:    " dup part-entry>start-sect c@ .d
        !           108:    cr ." part-entry>start-cyl:     " dup part-entry>start-cyl  c@ .d
        !           109:    cr ." part-entry>id:            " dup part-entry>id c@ .d
        !           110:    cr ." part-entry>end-head:      " dup part-entry>end-head c@ .d
        !           111:    cr ." part-entry>end-sect:      " dup part-entry>end-sect c@ .d
        !           112:    cr ." part-entry>end-cyl:       " dup part-entry>end-cyl c@ .d
        !           113:    cr ." part-entry>sector-offset: " dup part-entry>sector-offset l@-le .d
        !           114:    cr ." part-entry>sector-count:  " dup part-entry>sector-count l@-le .d
        !           115:    cr
        !           116: ;
        !           117: 
        !           118: : (.name) r@ begin cell - dup @ <colon> = UNTIL xt>name cr type space ;
        !           119: 
        !           120: : init-block ( -- )
        !           121:    s" block-size" ['] $call-parent CATCH IF ABORT" parent has no block-size." THEN
        !           122:    to block-size
        !           123:    d# 2048 alloc-mem
        !           124:    dup d# 2048 erase
        !           125:    to block
        !           126:    debug-disk-label? IF
        !           127:       ." init-block: block-size=" block-size .d ." block=0x" block u. cr
        !           128:    THEN
        !           129: ;
        !           130: 
        !           131: 
        !           132: \ This word returns true if the currently loaded block has _NO_ MBR magic
        !           133: : no-mbr? ( -- true|false )
        !           134:    0 read-sector block mbr>magic w@-le aa55 <>
        !           135: ;
        !           136: 
        !           137: : pc-extended-partition? ( part-entry-addr -- true|false )
        !           138:    part-entry>id c@      ( id )
        !           139:    dup 5 = swap          ( true|false id )
        !           140:    dup f = swap          ( true|false true|false id )
        !           141:    85 =                  ( true|false true|false true|false )
        !           142:    or or                 ( true|false )
        !           143: ;
        !           144: 
        !           145: : partition>part-entry ( partition -- part-entry )
        !           146:    1- /partition-entry * block mbr>partition-table +
        !           147: ;
        !           148: 
        !           149: : partition>start-sector ( partition -- sector-offset )
        !           150:    partition>part-entry part-entry>sector-offset l@-le
        !           151: ;
        !           152: 
        !           153: : count-dos-logical-partitions ( -- #logical-partitions )
        !           154:    no-mbr? IF 0 EXIT THEN
        !           155:    0 5 1 DO                                ( current )
        !           156:       i partition>part-entry               ( current part-entry )
        !           157:       dup pc-extended-partition? IF
        !           158:          part-entry>sector-offset l@-le    ( current sector )
        !           159:          dup to part-start to lpart-start  ( current )
        !           160:          BEGIN
        !           161:             part-start read-sector          \ read EBR
        !           162:             1 partition>start-sector IF
        !           163:                \ ." Logical Partition found at " part-start .d cr
        !           164:                1+
        !           165:             THEN \ another logical partition
        !           166:             2 partition>start-sector
        !           167:             ( current relative-sector )
        !           168:             ?dup IF lpart-start + to part-start false ELSE true THEN
        !           169:          UNTIL
        !           170:       ELSE
        !           171:          drop
        !           172:       THEN
        !           173:    LOOP
        !           174: ;
        !           175: 
        !           176: : (get-dos-partition-params) ( ext-part-start part-entry -- offset count active? id )
        !           177:    dup part-entry>sector-offset l@-le rot + swap ( offset part-entry )
        !           178:    dup part-entry>sector-count l@-le swap        ( offset count part-entry )
        !           179:    dup part-entry>active c@ 80 = swap            ( offset count active? part-entry )
        !           180:    part-entry>id c@                              ( offset count active? id )
        !           181: ;
        !           182: 
        !           183: : find-dos-partition ( partition# -- false | offset count active? id true )
        !           184:    to partition 0 to part-start 0 to part-offset
        !           185: 
        !           186:    \ no negative partitions
        !           187:    partition 0<= IF 0 to partition false EXIT THEN
        !           188: 
        !           189:    \ load MBR and check it
        !           190:    no-mbr? IF 0 to partition false EXIT THEN
        !           191: 
        !           192:    partition 4 <= IF \ Is this a primary partition?
        !           193:       0 partition partition>part-entry
        !           194:       (get-dos-partition-params)
        !           195:       \ FIXME sanity checks?
        !           196:       true EXIT
        !           197:    ELSE
        !           198:       partition 4 - 0 5 1 DO                      ( logical-partition current )
        !           199:          i partition>part-entry                   ( log-part current part-entry )
        !           200:          dup pc-extended-partition? IF
        !           201:             part-entry>sector-offset l@-le        ( log-part current sector )
        !           202:             dup to part-start to lpart-start      ( log-part current )
        !           203:             BEGIN
        !           204:                part-start read-sector             \ read EBR
        !           205:                1 partition>start-sector IF        \ first partition entry
        !           206:                   1+ 2dup = IF                    ( log-part current )
        !           207:                      2drop
        !           208:                      part-start 1 partition>part-entry
        !           209:                      (get-dos-partition-params)
        !           210:                      true UNLOOP EXIT
        !           211:                   THEN
        !           212:                   2 partition>start-sector
        !           213:                   ( log-part current relative-sector )
        !           214: 
        !           215:                   ?dup IF lpart-start + to part-start false ELSE true THEN
        !           216:                ELSE
        !           217:                   true
        !           218:                THEN
        !           219:             UNTIL
        !           220:          ELSE
        !           221:             drop
        !           222:          THEN
        !           223:       LOOP
        !           224:       2drop false
        !           225:    THEN
        !           226: ;
        !           227: 
        !           228: : try-dos-partition ( -- okay? )
        !           229:    \ Read partition table and check magic.
        !           230:    no-mbr? IF cr ." No DOS disk-label found." cr false EXIT THEN
        !           231: 
        !           232:    count-dos-logical-partitions TO dos-logical-partitions
        !           233: 
        !           234:    debug-disk-label? IF
        !           235:       ." Found " dos-logical-partitions .d ." logical partitions" cr
        !           236:       ." Partition = " partition .d cr
        !           237:    THEN
        !           238: 
        !           239:    partition 1 5 dos-logical-partitions +
        !           240:    within 0= IF
        !           241:       cr ." Partition # not 1-" 4 dos-logical-partitions + . cr false EXIT
        !           242:    THEN
        !           243: 
        !           244:    \ Could/should check for valid partition here...  the magic is not enough really.
        !           245: 
        !           246:    \ Get the partition offset.
        !           247: 
        !           248:    partition find-dos-partition IF
        !           249:      ( offset count active? id )
        !           250:      2drop drop
        !           251:      block-size * to part-offset
        !           252:      true
        !           253:    ELSE
        !           254:      false
        !           255:    THEN
        !           256: ;
        !           257: 
        !           258: \ Check for an ISO-9660 filesystem on the disk
        !           259: \ : try-iso9660-partition ( -- true|false )
        !           260: \ implement me if you can ;-)
        !           261: \ ;
        !           262: 
        !           263: 
        !           264: \ Check for an ISO-9660 filesystem on the disk
        !           265: \ (cf. CHRP IEEE 1275 spec., chapter 11.1.2.3)
        !           266: : has-iso9660-filesystem  ( -- TRUE|FALSE )
        !           267:    \ Seek to the begining of logical 2048-byte sector 16
        !           268:    \ refer to Chapter C.11.1 in PAPR 2.0 Spec
        !           269:    \ was: 10 read-sector, but this might cause trouble if you
        !           270:    \ try booting an ISO image from a device with 512b sectors.
        !           271:    10 800 * 0 seek drop      \ seek to sector
        !           272:    block 800 read drop       \ read sector
        !           273:    \ Check for CD-ROM volume magic:
        !           274:    block c@ 1 =
        !           275:    block 1+ 5 s" CD001"  str=
        !           276:    and
        !           277:    dup IF 800 to block-size THEN
        !           278: ;
        !           279: 
        !           280: 
        !           281: \ Load from first active DOS boot partition.
        !           282: 
        !           283: \ NOTE: block-size is always 512 bytes for DOS partition tables.
        !           284: 
        !           285: : load-from-dos-boot-partition ( addr -- size )
        !           286:    no-mbr? IF FALSE EXIT THEN  \ read MBR and check for DOS disk-label magic
        !           287: 
        !           288:    count-dos-logical-partitions TO dos-logical-partitions
        !           289: 
        !           290:    debug-disk-label? IF
        !           291:       ." Found " dos-logical-partitions .d ." logical partitions" cr
        !           292:       ." Partition = " partition .d cr
        !           293:    THEN
        !           294: 
        !           295:    \ Now walk through the partitions:
        !           296:    5 dos-logical-partitions + 1 DO
        !           297:       \ ." checking partition " i .
        !           298:       i find-dos-partition IF        ( addr offset count active? id )
        !           299:          41 = and                    ( addr offset count prep-boot-part? )
        !           300:          IF                          ( addr offset count )
        !           301:             max-prep-partition-blocks min  \ reduce load size
        !           302:             swap                     ( addr count offset )
        !           303:             block-size * to part-offset
        !           304:             0 0 seek drop            ( addr offset )
        !           305:             block-size * read        ( size )
        !           306:             UNLOOP EXIT
        !           307:          ELSE
        !           308:             2drop                    ( addr )
        !           309:          THEN
        !           310:       THEN
        !           311:    LOOP
        !           312:    drop 0
        !           313: ;
        !           314: 
        !           315: 
        !           316: \ load from a bootable partition
        !           317: 
        !           318: : load-from-boot-partition ( addr -- size )
        !           319:    load-from-dos-boot-partition
        !           320:    \ More boot partition formats ...
        !           321: ;
        !           322: 
        !           323: 
        !           324: 
        !           325: \ Extract the boot loader path from a bootinfo.txt file
        !           326: \ In: address and length of buffer where the bootinfo.txt has been loaded to.
        !           327: \ Out: string address and length of the boot loader (within the input buffer)
        !           328: \      or a string with length = 0 when parsing failed.
        !           329: 
        !           330: \ Here is a sample bootinfo file:
        !           331: \ <chrp-boot>
        !           332: \   <description>Linux Distribution</description>
        !           333: \   <os-name>Linux</os-name>
        !           334: \   <boot-script>boot &device;:1,\boot\yaboot.ibm</boot-script>
        !           335: \   <icon size=64,64 color-space=3,3,2>
        !           336: \     <bitmap>[..]</bitmap>
        !           337: \   </icon>
        !           338: \ </chrp-boot>
        !           339: 
        !           340: : parse-bootinfo-txt  ( addr len -- str len )
        !           341:    2dup s" <boot-script>" find-substr       ( addr len pos1 )
        !           342:    2dup = IF
        !           343:       \ String not found
        !           344:       3drop 0 0 EXIT
        !           345:    THEN
        !           346:    dup >r - swap r> + swap                  ( addr1 len1 )
        !           347:    2dup [char] \ findchar drop              ( addr1 len1 pos2 )
        !           348:    dup >r - swap r> + swap                  ( addr2 len2 )
        !           349:    2dup s" </boot-script>" find-substr nip  ( addr2 len3 )
        !           350: ;
        !           351: 
        !           352: \ Try to load \ppc\bootinfo.txt from the disk (used mainly on CD-ROMs), and if
        !           353: \ available, get the boot loader path from this file and load it.
        !           354: \ See the "CHRP system binding to IEEE 1275" specification for more information
        !           355: \ about bootinfo.txt. An example file can be found in the comment of
        !           356: \ parse-bootinfo-txt ( addr len -- str len )
        !           357: 
        !           358: : load-chrp-boot-file ( addr -- size )
        !           359:    \ Create bootinfo.txt path name and load that file:
        !           360:    my-self parent ihandle>phandle node>path
        !           361:    s" :\ppc\bootinfo.txt" $cat strdup       ( addr str len )
        !           362:    open-dev dup 0= IF 2drop 0 EXIT THEN
        !           363:    >r dup                                   ( addr addr R:ihandle )
        !           364:    dup s" load" r@ $call-method             ( addr addr size R:ihandle )
        !           365:    r> close-dev                             ( addr addr size )
        !           366: 
        !           367:    \ Now parse the information from bootinfo.txt:
        !           368:    parse-bootinfo-txt                       ( addr fnstr fnlen )
        !           369:    dup 0= IF 3drop 0 EXIT THEN
        !           370:    \ Create the full path to the boot loader:
        !           371:    my-self parent ihandle>phandle node>path ( addr fnstr fnlen nstr nlen )
        !           372:    s" :" $cat 2swap $cat strdup             ( addr str len )
        !           373:    \ Update the bootpath:
        !           374:    2dup encode-string s" bootpath" set-chosen
        !           375:    \ And finally load the boot loader itself:
        !           376:    open-dev dup 0= IF ." failed to load CHRP boot loader." 2drop 0 EXIT THEN
        !           377:    >r s" load" r@ $call-method              ( size R:ihandle )
        !           378:    r> close-dev                             ( size )
        !           379: ;
        !           380: 
        !           381: \ parse partition number from my-args
        !           382: 
        !           383: \ my-args has the following format
        !           384: \ [<partition>[,<path>]]
        !           385: 
        !           386: \ | example my-args  | example boot command      |
        !           387: \ +------------------+---------------------------+
        !           388: \ | 1,\boot\vmlinuz  | boot disk:1,\boot\vmlinuz |
        !           389: \ | 2                | boot disk:2               |
        !           390: 
        !           391: \ 0 means the whole disk, this is the same behavior
        !           392: \ as if no partition is specified (yaboot wants this).
        !           393: 
        !           394: : parse-partition ( -- okay? )
        !           395:    0 to partition
        !           396:    0 to part-offset
        !           397: 
        !           398:    my-args to args-len to args
        !           399: 
        !           400:    \ Fix up the "0" thing yaboot does.
        !           401:    args-len 1 = IF args c@ [char] 0 = IF 0 to args-len THEN THEN
        !           402: 
        !           403:    \ Check for "full disk" arguments.
        !           404:    my-args [char] , findchar 0= IF true EXIT THEN drop \ no comma
        !           405:    my-args [char] , split to args-len to args
        !           406:    dup 0= IF 2drop true EXIT THEN \ no first argument
        !           407: 
        !           408:    \ Check partition #.
        !           409:    base @ >r decimal $number r> base !
        !           410:    IF cr ." Not a partition #" false EXIT THEN
        !           411: 
        !           412:    \ Store part #, done.
        !           413:    to partition
        !           414:    true
        !           415: ;
        !           416: 
        !           417: 
        !           418: \ try-files and try-partitions
        !           419: 
        !           420: : (interpose-filesystem) ( str len -- )
        !           421:    find-package IF args args-len rot interpose THEN
        !           422: ;
        !           423: 
        !           424: : try-dos-files ( -- found? )
        !           425:    no-mbr? IF false EXIT THEN
        !           426: 
        !           427:    \ block 0 byte 0-2 is a jump instruction in all FAT
        !           428:    \ filesystems.
        !           429:    \ e9 and eb are jump instructions in x86 assembler.
        !           430:    block c@ e9 <> IF
        !           431:       block c@ eb <>
        !           432:       block 2+ c@ 90 <> or
        !           433:       IF false EXIT THEN
        !           434:    THEN
        !           435:    s" fat-files" (interpose-filesystem)
        !           436:    true
        !           437: ;
        !           438: 
        !           439: : try-ext2-files ( -- found? )
        !           440:    2 read-sector               \ read first superblock
        !           441:    block d# 56 + w@-le         \ fetch s_magic
        !           442:    ef53 <> IF false EXIT THEN  \ s_magic found?
        !           443:    s" ext2-files" (interpose-filesystem)
        !           444:    true
        !           445: ;
        !           446: 
        !           447: 
        !           448: : try-iso9660-files
        !           449:    has-iso9660-filesystem 0= IF false exit THEN
        !           450:    s" iso-9660" (interpose-filesystem)
        !           451:    true
        !           452: ;
        !           453: 
        !           454: : try-files ( -- found? )
        !           455:    \ If no path, then full disk.
        !           456:    args-len 0= IF true EXIT THEN
        !           457: 
        !           458:    try-dos-files IF true EXIT THEN
        !           459:    try-ext2-files IF true EXIT THEN
        !           460:    try-iso9660-files IF true EXIT THEN
        !           461: 
        !           462:    \ ... more filesystem types here ...
        !           463: 
        !           464:    false
        !           465: ;
        !           466: 
        !           467: : try-partitions ( -- found? )
        !           468:    try-dos-partition IF try-files EXIT THEN
        !           469:    \ try-iso9660-partition IF try-files EXIT THEN
        !           470:    \ ... more partition types here...
        !           471:    false
        !           472: ;
        !           473: 
        !           474: \ Interface functions for disk-label package
        !           475: \ as defined by IEEE 1275-1994 3.8.1
        !           476: 
        !           477: : close ( -- )
        !           478:    debug-disk-label? IF ." Closing disk-label: block=0x" block u. ." block-size=" block-size .d cr THEN
        !           479:    block d# 2048 free-mem
        !           480: ;
        !           481: 
        !           482: 
        !           483: : open ( -- true|false )
        !           484:    init-block
        !           485: 
        !           486:    parse-partition 0= IF
        !           487:       close
        !           488:       false EXIT
        !           489:    THEN
        !           490: 
        !           491:    partition IF
        !           492:        try-partitions
        !           493:    ELSE
        !           494:        try-files
        !           495:    THEN
        !           496:    dup 0= IF debug-disk-label? IF ." not found." cr THEN close THEN \ free memory again
        !           497: ;
        !           498: 
        !           499: 
        !           500: \ Boot & Load w/o arguments is assumed to be boot from boot partition
        !           501: 
        !           502: : load ( addr -- size )
        !           503:    debug-disk-label? IF
        !           504:       ." load: " dup u. cr
        !           505:    THEN
        !           506: 
        !           507:    args-len IF
        !           508:       TRUE ABORT" Load done w/o filesystem"
        !           509:    ELSE
        !           510:       partition IF
        !           511:          0 0 seek drop
        !           512:          200000 read
        !           513:       ELSE
        !           514:          has-iso9660-filesystem IF
        !           515:              dup load-chrp-boot-file ?dup 0 > IF nip EXIT THEN
        !           516:          THEN
        !           517:          load-from-boot-partition
        !           518:          dup 0= ABORT" No boot partition found"
        !           519:       THEN
        !           520:    THEN
        !           521: ;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.