[SLOF] [PATCH 3/4] Add a global "dir" method

Alexey Kardashevskiy aik at ozlabs.ru
Mon Jul 25 15:45:40 AEST 2016


On 07/07/16 12:09, Benjamin Herrenschmidt wrote:
> This adds a method akin to "boot" and "load" which takes the subsequent
> command line arguments, parses them as a device specification and
> calls the dir method on said device

How is it supposed to work exactly? I made an 4G image, formatted as
"mkdosfs -F 32 -I /dev/sdb" and passed to QEMU as an USB stick:


0 > devalias
scsi : /pci at 800000020000000/usb at 0/storage at 1
disk : /pci at 800000020000000/usb at 0/storage at 1/disk at 101000000000000
usb0 : /pci at 800000020000000/usb at 0
hvterm : /vdevice/vty at 71000100
nvram : /vdevice/nvram at 71000000 ok
0 > dir disk
Directory of: /pci at 800000020000000/usb at 0/storage at 1/disk at 101000000000000 ...
no dir method on target !

 ok
0 > dir disk,0
Directory of: disk,0 ...  ok
0 >    ok
0 >




> 
> Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> ---
>  slof/fs/boot.fs               | 15 ++++++++++++
>  slof/fs/packages/fat-files.fs | 56 ++++++++++++++++++++++++++++++++++---------
>  2 files changed, 60 insertions(+), 11 deletions(-)
> 
> diff --git a/slof/fs/boot.fs b/slof/fs/boot.fs
> index e99a164..e436380 100644
> --- a/slof/fs/boot.fs
> +++ b/slof/fs/boot.fs
> @@ -174,6 +174,21 @@ defer go ( -- )
>  \ Generic device load method:
>  \ *
>  
> +: do-dir ( devstr len -- )
> +  cr ." Directory of: " 2dup type ."  ... "
> +  open-dev dup IF
> +    s" dir" 2 pick ['] $call-method CATCH IF
> +       ." no dir method on target !" cr
> +       3drop
> +    THEN
> +    close-dev cr
> +  ELSE drop THEN
> +;
> +
> +: dir ( "{devstring}" -- )
> +    parse-word de-alias do-dir
> +;
> +
>  : do-load ( devstr len -- img-size )	\ Device method wrapper
>     use-load-watchdog? IF
>        \ Set watchdog timer to 10 minutes, multiply with 2 because DHCP
> diff --git a/slof/fs/packages/fat-files.fs b/slof/fs/packages/fat-files.fs
> index 9e389eb..e5b08bd 100644
> --- a/slof/fs/packages/fat-files.fs
> +++ b/slof/fs/packages/fat-files.fs
> @@ -33,6 +33,8 @@ INSTANCE VARIABLE root-offset
>  INSTANCE VARIABLE cluster-offset
>  INSTANCE VARIABLE #clusters
>  
> +INSTANCE VARIABLE dir?
> +
>  : seek  s" seek" $call-parent ;
>  : read  s" read" $call-parent ;
>  
> @@ -54,7 +56,7 @@ CREATE fat-buf 8 allot
>    fat-buf 8 read 8 <> ABORT" fat-files read-fat: read failed"
>    fat-buf 8c@ bxjoin fat-type @ dup >r 2* #split drop r> #split
>    rot IF swap THEN drop ;
> -  
> +
>  INSTANCE VARIABLE next-cluster
>  
>  : read-cluster ( cluster# -- )
> @@ -129,14 +131,35 @@ CREATE dos-name b allot
>  : find-file ( dir-cluster name len -- cluster file-len is-dir? true | false )
>    make-dos-name read-dir BEGIN (find-file) 0= WHILE next-cluster @ WHILE
>    next-cluster @ read-cluster REPEAT false ELSE true THEN ;
> -: find-path ( dir-cluster name len -- cluster file-len true | false )
> -  dup 0= IF 3drop false ."  empty name " EXIT THEN
> -  over c@ [char] \ = IF 1 /string  RECURSE EXIT THEN
> -  [char] \ split 2>r find-file 0= IF 2r> 2drop false ."  not found " EXIT THEN
> -  r@ 0<> <> IF 2drop 2r> 2drop false ."  no dir<->file match " EXIT THEN
> -  r@ 0<> IF drop 2r> RECURSE EXIT THEN
> -  2r> 2drop true ;
> -  
> +
> +: find-path ( dir-cluster name len -- cluster file-len is-dir? true | false )
> +  dup 0= IF
> +    \ empty name, assume directory
> +    2drop 0 true true EXIT
> +  THEN
> +  \ Strip leading backslashes
> +  over c@ [char] \ = IF
> +    1 /string  RECURSE EXIT
> +  THEN
> +  \ Split at backslash
> +  [char] \ split
> +  \ Store right side on return stack
> +  2>r
> +  find-file
> +  0= IF
> +    2r> 2drop false ."  not found " EXIT
> +  THEN
> +  \ right side (from stack) has non-0 len, must be a dir
> +  dup 0= r@ 0<> and IF
> +     3drop 2r> 2drop false ." path component not a dir " EXIT
> +  THEN
> +  r@ 0<> IF
> +    2drop 2r> RECURSE EXIT
> +  THEN
> +  2r> 2drop
> +  true
> +;
> +
>  : do-super ( -- )
>    0 200 read-data
>    data @ 0b + 2c@ bwjoin bytes/sector !
> @@ -203,7 +226,18 @@ INSTANCE VARIABLE pos-in-data
>    file-len @ read dup file-len @ <> ABORT" fat-files: failed loading file" ;
>  
>  : close  free-data ;
> +
> +: dir
> +  dir? @ IF file-cluster @ .dir ELSE ." not a directory!" cr THEN
> +  ;
> +
>  : open
>    do-super
> -  0 my-args find-path 0= IF close false EXIT THEN
> -  file-len !  file-cluster !  0 0 seek 0= ;
> +  0 my-args find-path
> +  0= IF free-data false EXIT
> +  THEN
> +  dir? ! file-len !  file-cluster !
> +  dir? @ IF
> +    0 0 seek 0=
> +  ELSE true THEN
> +;
> 


-- 
Alexey


More information about the SLOF mailing list