duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

drive.txt (2893B) - raw


      1 # Drive
      2 
      3 The Drive struct offers a unified API to read and write to mass storage.  It
      4 does so in blocks of bytes of a definite size which we call "sector".  Sectors
      5 in the Drive API are organized in a linear manner (LBA, Logical Block
      6 Addressing). If the underlying mass storage driver interfaces with a CHS
      7 (cylinder, head, sector) system, it's the driver's responsibility to convert LBA
      8 to CHS.
      9 
     10 The /lib/drive unit contains utilities around the Drive structure. This unit in
     11 split in two, between /lib/drivelo and lib/drive. /lib/drivelo is designed to be
     12 used at boot time. /lib/drive complements it with additional features.
     13 
     14 Fields:
     15 
     16 secsz   size in bytes of each sector read and written by the driver.
     17         It's often 512.
     18 seccnt  Number of sectors in the drive
     19 
     20 Methods:
     21 
     22 :sec@ ( sec dst drv -- )
     23   Read sector "sec" in memory address "dst", which needs to be a buffer at least
     24   "secsz" in size. "drv" is a pointer to a Drive structure.
     25 
     26 :sec! ( sec src drv -- )
     27   Write sector "sec" from memory address "src".
     28 
     29 ## SectorWindow
     30 
     31 A SectorWindow is a buffer referencing one or more sectors and holding one
     32 sector in memory. It manages the "dirty" status of the buffer and makes it easy
     33 to seek within the window, automatically managing buffer status.
     34 
     35 For example, one could open a SectorWindow of 4 512b sectors, starting at sector
     36 $2a. The buffer would begin holding sector $2a in its :buf(. The user could
     37 :seek relative address $212 within it, which would make it select sector $2b and
     38 return address $12 relative to :buf(. If the dirty flag is set, the buffer
     39 ensures that the contents is saved before loading a new one.
     40 
     41 Fields:
     42 
     43 drv     Target Drive
     44 fsec    First sector of the window
     45 cnt     Number of sectors in the window
     46 sec     Sector currently in buffer
     47 dirty   Whether the buffer is dirty
     48 
     49 Words:
     50 
     51 :new ( drv -- secwin )
     52   Create a new buffer targeting Drive "drv", on sector 0, cnt 1. Current buffer
     53   starts uninitialized.
     54 
     55 :buf( ( self -- a )
     56   Address of the buffer.
     57 
     58 :)buf ( self -- a )
     59   End of the buffer.
     60 
     61 :move ( fsec cnt self -- )
     62   Move window to "fsec" with "cnt" sectors. This doesn't change or flush the
     63   current buffer.
     64 
     65 :fulldrv ( self -- )
     66   Move the window so that it spans the whole drive.
     67 
     68 :load ( sec self -- )
     69   Load sector "sec" in the buffer. Aborts if outside the window.
     70 
     71 :flush ( self -- )
     72   If buffer is dirty, save it.
     73 
     74 :seek ( pos self -- a? n-or-0 )
     75   Load, if needed, the correct sector so that the position "pos", in bytes
     76   relative to the beginning of "fsec", is available in the buffer. Returns its
     77   address in "a" as well as the number of bytes that can be read before the end
     78   of the buffer is reaches, as "n". If "pos" is outside the window, "n" is 0 and
     79   "a" is absent.
     80 
     81 :next ( self -- a? n-or-0 )
     82   :seek the first byte of the sector following the one currently in the buffer.
     83 
     84 :dirty! ( self -- )
     85   Make the buffer dirty.