home *** CD-ROM | disk | FTP | other *** search
- An Explanation of AmigaDOS Storage Device Structure
-
- In order for you to use a disk editor to its full disk-saving/disk-altering
- potential, you must first understand the structure of an AmigaDOS device.
- References will be made to a P.D. disk editor called 'Sectorama', though the
- basic information and principals presented in this doc will be applicable to
- all disk editors. Note that to avoid confusion and to provide immediately
- applicable info, the block formats presented in this doc are specifically for
- 512 byte blocks. For larger blocks, the size of the Hash Table will vary and
- all info after the hash table will be displaced ahead of the hash table so
- the secondary-type word is at the end of the block. All devices I know of to
- this point use a 512 byte block.
-
- This document is basically written in two parts. The first part is an
- explanation of what each word in each type of block, how various types
- of blocks are structured, and how all these blocks relate to one another on
- an AmigaDOS storage device. The second part is an explanation of how to do
- things with a disk editor such as sectorama.
-
-
-
- I) BLOCK BASICS
- ============
-
- Generally, each block on an AmigaDOS device contains a checksum, a header
- key whose value is the disk address of the block, and a block type which tells
- you what type of block this is so you know what format that particular block
- uses. Note that when I use the term, 'block', I am referring to a 512 byte
- chunk of storage space on an AmigaDOS device. For example, on a floppy or
- hard drive, a block refers to a 512 byte sector. In VDO: and RAM:, a block
- refers to 512 contiguous bytes somewhere in memory. Also note that the size
- of each datum in a block is a 32 bit word. For all blocks, the first
- six words are as follows:
-
- +--------------------+
- 0 | Block Type |
- +--------------------+
- 1 | Header Key |
- +--------------------+
- 2 | Number or count |
- +--------------------+
- 3 | Table or Data size |
- +--------------------+
- 4 | First or next data |
- +--------------------+
- 5 | Checksum |
- +--------------------+
- : :
-
- Block Type - This identifies the general size and structure of this block.
- It currently has one of three values:
-
- T.SHORT = 00000002 This indicates the block is at the head of
- a list (i.e. a HEADER BLOCK).
-
- T.LIST = 00000010 This indicates the block is a LIST BLOCK.
- A list block is a member of a linked list
- list blocks and contains a table of pointers
- to data blocks.
-
- T.DATA = 00000008 This indicates the block is a DATA BLOCK.
- A data block is simply a block that contains
- data and will be described later in this
- doc.
-
- Header Key - This 32-bit word is the device's address for this block. It
- is a pointer to this block.
-
- Number or Count - If this not a data block, this is a total count of data
- blocks (and, hence, the highest sequence number of any
- data block) pointed-to by this block.
-
- - If this block is a data block, this number is the sequence
- number of this data block. That is, it tells us this data
- block is the n'th member of a list of data blocks.
-
- Table or Data Size - This is a count of how many 32-bit words there are in
- the table or data starting at word # 6 in this block.
-
-
- First or Next Data - This is a pointer to the data block following this block.
- If this block is a header or a list block, then this
- pointer will point to the first data block in a list
- of data blocks.
-
- Checksum - When this number and the values of all other words in this block
- are added up, the sum must be zero. This is how bad blocks are
- detected by AmigaDOS.
-
- For all types of blocks excepting data blocks, the last four words have the
- following format:
-
- : :
- +----------------+
- 7C | Hashchain |
- +----------------+
- 7D | Parent |
- +----------------+
- 7E | Extension |
- +----------------+
- 7F | Secondary Type |
- +----------------+
-
- Hashchain - points to the next entry on this hash chain.
-
- Parent - pointer to the parent directory. The parent directory is the
- directory block which either points to this block or points to a
- linked list (i.e. hash chain) of which this block is a member.
-
- Extension - pointer to the next extension block which essentially extends the
- table which starts at word # 6 of this block.
-
- Secondary Type - This exactly identifies what kind of block this is. This
- tells us exactly what function and structure this block has.
- The possible codes in this word are:
-
- ST.ROOT = 00000001 This identifies the ROOT BLOCK, which
- is the device's 'root directory'.
- This block ultimately points to all
- the files and directories on the
- storage device.
-
- ST.USERDIR = 00000002 This identifies a USER DIRECTORY BLOCK
- which points to all the files and
- directories which have been defined
- for this directory.
-
- ST.FILE = FFFFFFFD This identifies either a FILE HEADER
- BLOCK, if the block type at word # 1
- is T.SHORT, or a FILE LIST BLOCK if
- the block type is T.LIST.
- A FILE HEADER BLOCK points to all the
- data blocks that make up the file. If
- there are too many data blocks to be
- pointed to by this block, a list of
- FILE LIST BLOCKS is pointed-to by the
- extension pointer at word # 7E. A
- FILE LIST BLOCK simply extends the
- table and points to the next FILE LIST
- BLOCK if more data block pointers are
- required.
-
- Note that the above-mentioned word definitions are not applicable to some
- block types and functions. Where their function is non-applicable, their
- value is usually set at zero.
-
-
-
- II) THE ROOT BLOCK
- ==============
-
- The block that ultimately points to everything on the disk is called the
- 'Root Block'. This block usually resides in the exact center of a storage
- device to minimize the distance a read/write head of a floppy or hard disk
- must move when travelling from an outer cylinder to the Root Block. The
- format of the Root Block is as follows:
-
- symbolic usual
- value value
- +----------------------+
- 0 | T.SHORT = 00000002 | Indicates this is a 512 byte header block
- +----------------------+
- 1 | 0 = 00000000 | Header Key (Always zero in a root block)
- +----------------------+
- 2 | 0 = 00000000 | Highest sequence number in chain (0 for root)
- +----------------------+
- 3 | HT SIZE = 00000048 | Hashtable size (=blocksize-56 = 512/4-56 words)
- +----------------------+
- 4 | 0 = 00000000 |
- +----------------------+
- 5 | CHECKSUM = ? | Checksum for this block
- ----+----------------------+
- { 6 | |
- { | Hash Table |
- { to : :
- { : :
- { 4D | |
- ----+----------------------+
- 4E | BMFLAG = FFFFFFFF | True (all F's) if device or disk bitmap valid
- ----+----------------------+
- { 4F | |
- { | Bitmap Pages |
- { to : :
- { : :
- { 68 | |
- ----+----------------------+
- 69 | DAYS = ? | Volume last altered date and time.
- +----------------------+ Date is in packed format.
- 6A | MINS = ? | Time is rated in minutes and ticks.
- +----------------------+ One tick is 1/60th of a second.
- 6B | TICKS = ? |
- ----+----------------------+
- { 6C | | Volume name as a BCPL string of 30 characters
- { | Disk Name | or less, though the amount of space to store
- { to : : this string always remains the same size.
- { : :
- { 78 | |
- ----+----------------------+
- 79 |CREATEDAYS = ? | Date and time when this volume was created.
- +----------------------+ Format here, as well as all date/time data
- 7A |CREATEMINS = ? | presented in other types of blocks are in the
- +----------------------+ format shown for the above volume last altered
- 7B |CREATETICKS= ? | date and time.
- +----------------------+
- 7C | 0 = 00000000 | Next entry on this hash chain (0 for root)
- +----------------------+
- 7D | 0 = 00000000 | Parent directory (always 0 for root)
- +----------------------+
- 7E | 0 = 00000000 | Extension (always 0 for root)
- +----------------------+
- 7F | ST.ROOT = 00000001 | Secondary type indicates this is a Root Block
- +----------------------+
-
- -> What the heck is a HASH TABLE?
-
- A HASH TABLE is a table of pointers to files and to lists of files. To
- locate a particular file in the table, the name of the file is used to
- calculate where in the table it is to be located. This location may not be
- unique to the name of this file. In this case, the pointer will point to a
- linked list of file headers which must be traversed until the file header for
- the file we're searching for is found. This linked list is referred to as a
- HASH CHAIN.
-
- The actual searching-out of files will be discussed in more practical terms
- in the practical portion of this document.
-
- -> What things are pointed-to by pointers in a HASH TABLE?
-
- Each non-zero pointers in the hash table points to either a FILE HEADER
- BLOCK or a USER DIRECTORY BLOCK which, in turn, may have a hash chain pointer
- which will point to the next file header block or user directory block in
- the hash chain.
-
- -> What are bitmap pages?
-
- The words in the list of bitmap pages point to 512 byte blocks which
- simply map-out which blocks on the device are used, and which are free for
- usage. I don't yet understand how the bitmaps are set-up or maintained,
- but as soon as I find out, I'll slip the info into this document.
-
- -> What is a BCPL string?
-
- This is a string of bytes where the first byte indicates the number of
- characters in the string (say, 'n' characters), the next 'n' characters
- contain the ASCII values for the string, and the rest of the string is
- ignored. For example, on my Workbench disk, a hex dump of the string looks
- like this:
-
- 09576F72 6B62656E 63686F72 6B62656E .Workbenchorkben
- 63680000 00000000 00000000 00000000 ch..............
- 00000000 00000000 ........
-
- Where the 09 at the beginning specifies that only the next nine characters
- are valid characters of the string and the rest are ignored.
-
- Note that for the root block, zeros are always in the Header Key, Sequence
- Number, Hash cain, Parent, and Extension fields. This is because a ROOT BLOCK
- is always at a specific spot on the device (for a disk, it is exactly
- cenetered between the outer- and inner-most cylinders), it never require hash
- table extensions, it is not pointed-to by a hash table and is not part of a
- hash list, and it does not have a parent directory.
-
-
-
- III) USER DIRECTORY BLOCKS
- =====================
-
- A user directory block is created when a new directory is made in a storage
- device. It contains its own name and protection status, its parent directory,
- as well as a hash table pointing to files and user directories that have been
- placed into this directory. The hash table functions exactly the same way as
- that in the ROOT BLOCK. The format of a USER DIRECTORY BLOCK is as follows:
-
- symbolic usual
- value value
- +----------------------+
- 0 | T.SHORT = 00000002 | Indicates this is a 512 byte header block
- +----------------------+
- 1 | OWN KEY = ? | Header Key (pointer to this very block)
- +----------------------+
- 2 | 0 = 00000000 | Highest sequence number in chain (always zero)
- +----------------------+
- 3 | 0 = 00000000 |
- +----------------------+
- 4 | 0 = 00000000 |
- +----------------------+
- 5 | CHECKSUM = ? | Checksum for this block
- ----+----------------------+
- { 6 | |
- { | Hash Table |
- { to : :
- { : :
- { 4D | |
- ----+----------------------+
- 4E | SPARE = 00000000 |
- 4F | SPARE = 00000000 |
- +----------------------+
- 50 | PROTECT = ? | Protection bits (Read/Write/Execute/Delete)
- +----------------------+
- 51 | 0 = 00000000 | Unused (always zero)
- ----+----------------------+
- { 52 | |
- { | COMMENT | Stored as a BCPL string
- { to : : (up to 90 characters)
- { : :
- { 68 | |
- ----+----------------------+
- 69 | DAYS = ? | Directory creation date and time.
- +----------------------+
- 6A | MINS = ? |
- +----------------------+
- 6B | TICKS = ? |
- ----+----------------------+
- { 6C | |
- { | Directory Name | Directory name as a BCPL
- { to : : (up to 30 characters)
- { : :
- { 7B | |
- ----+----------------------+
- 7C |HASHCHAIN = ? | Next entry with same hash value
- +----------------------+
- 7D | PARENT = ? | Back pointer to parent directory
- +----------------------+
- 7E | 0 = 00000000 | Extension
- +----------------------+
- 7F | ST.ROOT = 00000002 | Secondary type (user directory block)
- +----------------------+
-
-
-
- IV) FILE HEADER BLOCK
- =================
-
- This block is the first block of any given file. It contains file
- information such as the name, size, protection status, creation date, and a
- pointer to the parent directory block of the file. It also contains a table
- of pointers to all the data blocks that make up the file. If there are more
- data blocks than there are pointers in the table of data block pointers (at
- words # 6 to 4D), an extension pointer is provided to a FILE LIST BLOCK which
- contains a similar table of data block pointers. If the file list block
- still doesn't provide enough pointers, it will provide yet another extension
- pointer to another FILE LIST BLOCK. This list of FILE LIST BLOCKS extends
- until enough pointers are provided to point to all the data blocks of the
- file.
-
- symbolic usual
- value value
- +----------------------+
- 0 | T.SHORT = 00000002 | Indicates this is a 512 byte header block
- +----------------------+
- 1 | OWN KEY = ? | Header Key (pointer to this very block)
- +----------------------+
- 2 |HIGHEST SEQ= ? | Number of data blocks pointed-to by this block
- +----------------------+
- 3 |DATA SIZE = ? |
- +----------------------+
- 4 |FIRST DATA = ? | Pointer to the first data block of the file
- +----------------------+
- 5 | CHECKSUM = ? | Checksum for this block
- ----+----------------------+
- { 6 | : |
- { : : : List of pointers to data blocks
- { to : : : (i.e. Data block keys)
- { | DATA BLOCK 3 |
- { | DATA BLOCK 2 |
- { 4D | DATA BLOCK 1 |
- ----+----------------------+
- 4E | SPARE = 00000000 |
- 4F | SPARE = 00000000 |
- +----------------------+
- 50 | PROTECT = ? | Protection bits (Read/Write/Execute/Delete)
- +----------------------+
- 51 | BYTESIZE = ? | Total size of file in bytes
- ----+----------------------+
- { 52 | |
- { | COMMENT | Stored as a BCPL string
- { to : : (up to 90 characters)
- { : :
- { 68 | |
- ----+----------------------+
- 69 | DAYS = ? | File creation date and time.
- +----------------------+
- 6A | MINS = ? |
- +----------------------+
- 6B | TICKS = ? |
- ----+----------------------+
- { 6C | |
- { | File Name | File name as a BCPL string
- { to : : (up to 30 characters)
- { : :
- { 7B | |
- ----+----------------------+
- 7C |HASHCHAIN = ? | Next entry with same hash value
- +----------------------+
- 7D | PARENT = ? | Back pointer to parent directory
- +----------------------+
- 7E |EXTENSION = ? | Pointer to a FILE LIST BLOCK (if required)
- +----------------------+
- 7F | ST.ROOT = FFFFFFFD | Secondary type (file header block)
- +----------------------+
-
-
-
- V) FILE LIST BLOCK
- ===============
-
- This type of block is used to extend the table of data block keys
- (pointers) of a FILE HEADER BLOCK when the table in the FILE HEADER BLOCK
- hasn't enough pointers to point to all the file's data blocks. If a FILE
- LIST BLOCK doesn't have enough pointers to point to the rest of the file's
- data blocks, the EXTENSION pointer of the block will point to yet another
- FILE LIST BLOCK. The extension list continues until enough pointers are
- provided for all the data blocks in the file.
-
- symbolic usual
- value value
- +----------------------+
- 0 | T.LIST = 00000010 | Indicates this is a file list block
- +----------------------+
- 1 | OWN KEY = ? | Header Key (pointer to this very block)
- +----------------------+
- 2 |BLOCK COUNT= ? | Number of data blocks pointed-to by this block
- +----------------------+
- 3 |DATA SIZE = 00000000 |
- +----------------------+
- 4 |FIRST DATA = 00000000 |
- +----------------------+
- 5 | CHECKSUM = ? | Checksum for this block
- ----+----------------------+
- { 6 | : |
- { : : : Extended list of pointers to data blocks
- { to : : : (i.e. Data block keys)
- { | DATA BLOCK 3 |
- { | DATA BLOCK 2 |
- { 4D | DATA BLOCK 1 |
- ----+----------------------+
- { 4E | |
- { | unused | unused (all zeros)
- { to : :
- { : :
- { 7B | |
- ----+----------------------+
- 7C | 0 = 00000000 | Next in hash list (always zero for list block)
- +----------------------+
- 7D | PARENT = ? | Points to the file header block of this file
- +----------------------+
- 7E |EXTENSION = ? | Points to the next FILE LIST BLOCK (if required)
- +----------------------+
- 7F | ST.ROOT = FFFFFFFD | Secondary type (file header block)
- +----------------------+
-
-
-
- VI) DATA BLOCK
- ==========
-
- A data block contains data from a file and is pointed-to by preceding
- data blocks and by a pointer in a table in either a FILE HEADER BLOCK or a
- FILE LIST BLOCK. Thus, the data block can be accessed directly from a header
- or list block of a file, or sequentially by following the linked list of data
- blocks. Each data block also points to the FILE HEADER BLOCK which describes
- the file which contains this data block. A sequence number is also present
- in a data block, and indicates that this data block is the n'th data block
- in the list of the file's data blocks.
-
- symbolic usual
- value value
- +----------------------+
- 0 | T.DATA = 00000008 | Indicates this is a data block
- +----------------------+
- 1 | HEADER = ? | Header key pointing to the file header block.
- +----------------------+
- 2 | SEQ NUM = ? | Sequence number
- +----------------------+
- 3 | DATA SIZE = 00000000 | Number of words of data in this block
- +----------------------+
- 4 | NEXT DATA = ? | Pointer to the next data block
- +----------------------+
- 5 | CHECKSUM = ? | Checksum for this block
- ----+----------------------+
- { 6 | |
- { | DATA |
- { to : :
- { : :
- { 7F | |
- +----------------------+
-
-
-
- VII) HOW DO THE BLOCKS FIT TOGETHER?
- ===============================
-
- The ROOT BLOCK is located at a fixed location, exactly between the highest
- and lowest addresses available on a storage device. The ROOT BLOCK contains
- a table of pointers (the hash table) to linked lists (hash chains) of USER
- DIRECTORY BLOCKS and FILE HEADER BLOCKS which describe user directories and
- files accessible from the root directory.
-
- A USER DIRECTORY BLOCK contains the name and protection status of a user
- directory, as well as a hash table containing pointers to hash chains of
- USER DIRECTORY BLOCKS and FILE HEADER BLOCKS which describe user directories
- and files accessible from that user directory. Since the USER DIRECTORY
- itself is a member of a hash chain, it also contains pointers to its parent
- directory block and to the next USER DIRECTORY BLOCK or FILE HEADER BLOCK in
- the header chain.
-
- A FILE HEADER BLOCK contains information describing the file it represents,
- as well as a table of pointers to DATA BLOCKS that make up the file. If
- there aren't enough pointers in this table to point to all the file's DATA
- BLOCKS, an EXTENSION pointer points to a list of FILE LIST BLOCKS which
- extend the table. Since the FILE HEADER BLOCK is a member of a hash chain,
- it contains pointers to its parent directory and to the next USER DIRECTORY
- BLOCK or FILE HEADER BLOCK in the header chain.
-
- A FILE LIST BLOCK contains a table of pointers to DATA BLOCKS and extends
- the table of the FILE HEADER BLOCK or FILE LIST BLOCK which points to this
- FILE LIST BLOCK. If there aren't enough pointers in this table to point to
- the remainder of the file's DATA BLOCKS, an EXTENSION pointer in the FILE
- LIST BLOCK points to the next FILE LIST BLOCK to extend its data block table.
-
- A DATA BLOCK's main content is data. It is part of a linked list of DATA
- BLOCKS and includes a pointer to the next DATA BLOCK in the list. It also
- includes a sequence number indicating that this DATA BLOCK is the n'th DATA
- BLOCK in the list. Each DATA BLOCK is pointed-to both by the preceding DATA
- BLOCK in the list, and by a pointer in a data block table in either a FILE
- HEADER BLOCK or a FILE LIST BLOCK. Each DATA BLOCK also contains a pointer
- to the FILE HEADER BLOCK which describes the file which the DATA BLOCK is a
- member of.
-
- Confused? Don't worry, practical stuff is coming up next...
-
-
-
- VIII) UNDERSTANDING YOUR DISK EDITOR
- ==============================
-
- Before we begin playing with a disk editor, I recommend that you create a
- backup of a densely populated disk, like your workbench, so that if a wrong
- key is pressed while looking through the backup, you haven't done damage to
- your one and only copy.
-
- a) A Look at Sectorama
- ===================
- For those of you lucky enough to have a copy of sectorama handy, fire it
- up and I can explain what all those obscure thingies on the right side and
- of the top line of the screen mean and where, from the block you are
- looking at, the information was taken.
-
- The lower right hand portion of the display identifies the storage
- device currently being examined by this sectorama display. It gives us
- the device name (as a volume name), the device unit number, and the
- filename of the device driver that communicates with the device.
-
- The display section immediately above this info contains hardware-
- dependant information. The middle column shows us the the sector, track
- cylinder, surface, and block numbers of the block currently being
- displayed. This information is all given in decimal values. All these
- statistics are all determined by a set of info used by the device driver.
- For a floppy, for example, these tell us on which cylinder the read/write
- head is currently positioned, which sector on which surface (top or bottom)
- is being read by the read/write head, and the hardware-specific track and
- block numbers for that sector. The rightmost column are device statistics.
- These tell us how many of each category there are on this device.
-
- Note that by pointing at any of the figures in the center column of this
- section, you can change the current values. By changing sector, surface,
- or block number, you can examine any sector of the device immediately.
-
- The section immediately above the hardware information contains
- information about (and from) the block currently being displayed:
-
- Date -refers to the creation date which is taken from word # 69.
-
- Time -is calculated from words # 6A (to get hours and minutes) and
- # 6B (to get seconds).
-
- Highest Seq # -is taken from word # 2 and refers to the number of
- words used in the table starting at word # 6.
-
- Data Size -refers to the size of the table at word # 6.
-
- Protect -refers to the protection status of a user directory block or
- a file header block and is taken from the value at word # 50
-
- File Bytes -refers to the size of a file in kilobytes. This value is
- 1/1000'th the value of word # 51.
-
- The section at the upper right corner of the display is a list of
- keyboard commands with current values beside them. All except the
- checksum are pointers to other blocks in the device. The checksum is the
- current block's checksum value taken from word # 5. This value must be
- recalculated every time you make an alteration to a block. The pointers
- shown beside each command are as follows:
-
- R-Go Root -points to the root directory of this disk. This pointer
- is a constant value which has been calculate for this
- storage device.
-
- P-Go Parent -points to a FILE HEADER BLOCK's or USER DIRECTORY BLOCK's
- parent directory block. This pointer is taken from
- word # 7D.
-
- C-Go Hash Chain -points to the next FILE HEADER BLOCK or USER
- DIRECTORY BLOCK in this blocks hash chain. This
- pointer is taken from word # 7C.
-
- X-Go Extension -points to the next FILE LIST BLOCK in an extension
- chain. This pointer is taken from word # 7E.
-
- H-Go Header -for DATA BLOCKS, this points to the FILE HEADER BLOCK
- to which this DATA BLOCK belongs.
- -for other blocks, this points to the block currently
- being examined.
- -in both cases, this pointer is taken from word # 1.
-
- For all the above commands, if you type the letter to initiate the
- command, sectorama will jump to the block corresponding to the pointer
- displayed beside the command.
-
- At the top of the display are three more information displays. On the
- left is the block number of the block currently being displayed. Next to
- that is the Type of the block being displayed. The block type is
- determined by word # 0, which contains the block type, and word # 7F,
- which contains the secondary type.
-
- Next to the block type is the Name of the block. This name may be a
- volume name or a directory name or a file name, depending on if this block
- is a ROOT BLOCK, a USER DIRECTORY BLOCK, or a FILE HEADER BLOCK,
- respectively.
-
-
- b) Sectorama commands
- ==================
- All the sectorama commands are adequately described in the documentation
- file that accompanies it.
-
-
- c) A Practical Session
- ===================
- i) Touring a floppy, a summary
- ---------------------------
- I suggest that as you progress through this little step-by-step
- blathering that each time you come across a new type of block, you
- compare the data being displayed by sectorama to the block
- descriptions shown above so that you become more familiar about where
- things are located in each type of block.
-
- The steps for performing the operations summarized below with
- Sectorama are described in detail, with a running commentary, in
- section ii) Touring a floppy with Sectorama. For following these
- steps with any other disk editor, I suggest that you quickly read
- through the Sectorama tour to familiarize yourself with what is
- being attempted, then attempt the summarized steps below to familiarize
- yourself with your disk editor and AmigaDOS.
-
- Steps 1 thru 8 will guide you from a disk's ROOT BLOCK, into a file
- and through all the data blocks in that file. A quick summary of
- these steps is as follows:
-
- Steps 9 thru 14 show you how to alter a block and write it to disk.
-
- _A step-by-step of the tour, in summary is as follows:
-
- / 1. Run the disk editor.
- |
- | 1a. (Load the root block. This is done automatically by Sectorama.)
- |
- | 2. Locate the 'c' directory by using the hash function.
- Part< 3. Load the USER DIRECTORY BLOCK for the c directory.
- 1a | 4. Locate the 'dir' command file by using the hash function.
- | 5. Load the FILE HEADER BLOCK for the 'dir' file.
- | 6. Load the first DATA BLOCK of the 'dir' file.
- | 7. Load and examine each consecutive DATA BLOCK of the 'dir' file until
- | the last DATA BLOCK in the file has been loaded and examined.
- \_8. Load the FILE HEADER BLOCK pointed-to by the final DATA BLOCK.
- _
- / 9. Locate and select the first word in the comment filed of the FILE
- | HEADER BLOCK for the 'dir' file.
- | 10. Edit the ASCII values of the comment field.
- Part< 11. Edit the hexadecimal value of the first byte of the first word of
- 1b | the comment field to insert the string length of the comment
- | created in step 10.
- | 12. Re-calculate the checksum for this block.
- | 13. Write the altered block to disk.
- \_14. Quit the disk editor.
-
-
-
- ii) Touring a floppy with Sectorama...
- ----------------------------------
-
-
- 1. O.K., get your disk editor up and running (if it isn't already)
- and begin examining a back-up copy of your workbench disk. For
- sectorama, the CLI command line for this if the disk was in df0:
- would look like:
-
- 1> run sec df0:
-
- What you will see on your display (in neato-keen hi-res) is data
- of the ROOT BLOCK of df0:. On top of the display is 'Type=ROOT DIR'
- which indicates that the block currently being displayed is a
- ROOT BLOCK.
-
- 2. Now that we are at the ROOT BLOCK, lets find the c directory. The
- first step for this is to find out what value we get when we use the
- hash function on the string 'c'. To do this you must envoke the hash
- function by picking 'COMPUTE HASH VALUE' under the SEARCH menu, then
- typing the file or directory name, in this case the letter c followed
- by a <RETURN>. This highlights the block address of the hash chain
- which contains the c directory.
-
- 3. Now that you've found the possible whereabouts of the c directory
- jump to it by hitting the j key. If (more likely than not) on top of
- the display is 'Name=c' then the display is currently displaying the
- contents of the c directory and the top of the display has
- 'Type=DIRECTORY' indicating that what is being displayed is a USER
- DIRECTORY BLOCK, which is essentially the c directory of df0:.
-
- 4. Now that we're at the c directory, let's look at a file containing
- loadable/executable code for a well-known function... say, the file
- called 'dir'. Envoke the hash function as before using the string
- dir. The block address of the hash chain that contains the dir file
- will be highlighted.
-
- 5. Press the j key to jump to the beginning of the hash chain which
- will have (again, more likely than not) 'Type=FILE Name=dir'
- displayed above the table of block data. The Type=FILE indicates that
- this is the header block for the file indicated by Name=dir. This is a
- fairly short file, so that all the block addresses for the DATA BLOCKS
- for this file are included in this block and that no extension blocks
- are required for this file, which is why the block address beside
- 'X-Go Extension=' is 00000000.
-
- Also notice that the block address beside 'D-Go Next Data' is the
- same as the last entry in the data table of this block (at word # 4D
- according to my version of dir). This is because data blocks are
- arranged in this table starting at the end of the table and working
- towards the beginning.
-
- 6. Let's take a look at the first DATA BLOCK, then, by hitting the
- d key to 'Go Next Data'. What will be displayed is the first DATA
- BLOCK of the dir file. On top of the display will be 'Type=DATA BLOCK'
- confirming that fact. Note that word # 04, which has the same value as
- is displayed beside D-Go Next Data =, points to the next DATA BLOCK for
- this file.
-
- 7. Let's traverse the entire list of DATA BLOCKS to see what the last
- one in the list looks like. You can do this by hitting the D key
- about 16 times or so. While you do this, note that the value beside
- H-Go Header = stays constant for each data block while all the other
- values remain constant. The value beside H-Go Header = points to
- the FILE HEADER BLOCK which owns the DATA BLOCK. If this ever changes
- as you are traversing a list of DATA BLOCKS, you KNOW there is a
- problem with the file. Also note that as you jump from block to block,
- the HISTORY list at the bottom of the display keeps track of your last
- eight jumps. This is a valuable feature when you overshoot a problem
- area and need to know where you've been in previous jumps. Also note
- that for each successive DATA BLOCK that you display, the sequence
- number displayed in the middle of the right part of the screen is
- incremented by one. This helps you figure out exactly where you are in
- the file you are looking through. If ever this sequence number jumps
- up or down by more that one, you know the DATA BLOCK is out of its
- proper sequence.
-
- 8. Once you've reach the end of the DATA BLOCK list, you will find that
- hitting the D key will now only cause the display to flash, indicating
- that this is indeed the end of the DATA BLOCK list for this file. Lets
- jump back to the FILE HEADER BLOCK for the 'dir' file by hitting the
- h key (for H-Go Header).
-
-
- 9. Now that we've jumped around the disk doing some block reading,
- let's get more adventurous. Let's modify a block on the disk. By
- comparing the FILE HEADER BLOCK description above, we note that the
- comment field in this block begins at word # 52 and ends at word # 68.
- Move your pointer to word # 52 and click your left mouse button to
- highlight it.
-
- 10. Next, press the A key to enter ASCII edit mode (the command list on
- the right of the display describes it as Edir ASCII). Now type a space
- and then some sort of short comment, being careful not to type past
- word #68. For example, I typed the comment ' dir, oh dir' beginning
- in word #52. Note that the delete key and backspace key do not work
- normally in this mode, and actually produce their own special ascii
- values. To re-type something, you must either move your pointer to the
- desired location and click, or use your cursor keys to move the
- highlighter to the desired character, then type your correction.
- To exit this edit mode, simply hit <RETURN>.
-
- 11. To make our comment a proper BCPL string, we must put a character
- count at word # 52. Count how many characters there are in your string
- and convert this number to hexadecimal. Next, enter the hexadecimal
- edit mode by hitting the e key (for Edit), type your two-digit
- hexadecimal value and hit return. For example, in my 'dir, oh dir'
- comment there are eleven characters. Eleven converts to 0B in
- hexadecimal, so I edit word #52, type 0B, and hit return.
-
- 12. Since we've altered the contents of this block, the checksum for
- this block is no longer valid. We must hit the k key to calculate a
- new checksum. When you have done this, you will note that the value
- beside K-Checksum = and at word # 05 have changed to the newly
- calculated checksum.
-
- 13. Note that any changes you have made so far haven't been written to
- disk at all. Nothing is ever written to disk until you actually write
- it by hitting the u key to 'Update block'. To incorporate your new
- file comment for the file called 'dir', hit the u key.
-
- 14. Then quit Sectorama, and list df0:c/dir to see the
- change that you've just made. Note that you may have to list the whole
- c directory to see the change since AmigaDOS keeps track of which
- sectors of which device it currently has in buffers, and will avoid
- fetching your modified sector if it is currently in df0:'s buffer.
-
-
- What we've just done is to examine a disk, seek-out a specific file,
- look through the file's data, then modify the FILE HEADER BLOCK of
- that file. What we haven't seen yet are two important data
- structures which we will look for now. Specifically, these structures
- are the hash chain, and the file list.
-
- 1. to 3. Same as steps 1. to 3. above. (Locate & load the c directory)
-
- 4. Now calculate the hash value for Echo using the Calculate Hash Value
- function. Write the highlighted number down.
-
- 5. Calculate the hash value for Quit using the same hash function used
- in step 4.
-
- 6. Calculate the hash value for Why using the hash function. You will
- find that the value you have written down for the value calculated for
- Why, Quit, and Echo are all identical, implying that if you jump to
- this number, you will have access to all three files.
- What this really means is that the FILE HEADER BLOCKS of these three
- files are members of the same hash chain.
-
- 7. Jump to the first file in the hash chain by hitting the j key. I
- cannot say exactly which FILE HEADER BLOCK you will be shown, since
- that depends on in what order the files in the chain were created on
- this disk. Note that the value beside P-Go Parent = is that of the
- USER DIRECTORY BLOCK of the directory containing this file, namely the
- c directory.
-
- 8. Note that the block address beside C-Go Hash Chain = is non-zero.
- At least, if the files Echo, Quit, and Why are in the c directory on
- this disk, the value will be non-zero. Otherwise, this demonstration
- will not be successful. To display the header of the next file or
- directory in this hash chain, hit the c key (indicated by C-Go Hash
- Chain).
-
- 9. Note that the value beside P-Go Parent hasn't changed. This is
- because all members of a hash chain always belong to the same
- directory. To traverse the hash chain and find the last FILE HEADER
- BLOCK or USER DIRECTORY BLOCK in the chain, keep hitting the c key
- until the value beside C-Go Hash Chain becomes zero. When this
- happens, further presses of the c key will merely cause the display
- to flash, indicating you are at the end of the hash chain.
-
- 10. Jump back to the ROOT BLOCK by hitting the r key.
-
-
- To find what an extension file looks like, we must look for a large
- file... one where the amount of data is large enough that more pointers
- are available in a FILE HEADER BLOCK's DATA BLOCK pointer table. A
- DATA BLOCK pointer table usually has 72 available entries. Since each
- BLOCK is 512 bytes long, we need a file that is over 72 x 512 = 36864
- bytes long. The Preferences file is about twice that length, so let's
- take a look at it.
-
- 11. Calculate the hash value for Preferences using the hash function.
-
- 12. Jump to the FILE HEADER BLOCK for the Preferences file by hitting
- the j key. You will note that all the entries in the DATA BLOCK
- pointer table in this FILE HEADER BLOCK are used-up. You will find
- the rest of the pointers required to point to the rest of the DATA
- BLOCKS for this file in the file list. The block number of the first
- FILE LIST BLOCK in the file list is shown beside X-Go Extension.
-
- 13. Hit the x key to jump to the first FILE LIST BLOCK. Note that the
- block number displayed beside P-Go Parent is the same as the block
- number of the FILE HEADER BLOCK to which this FILE LIST BLOCK belongs.
- Also note that the value beside X-Go Extension is now zero. If the
- required even more DATA BLOCKS, that is, if the file was longer than
- about 73kbytes, the value beside X-Go Extension would point to the next
- FILE LIST BLOCK in the file list.
-
- So, that pretty well wraps-up the tour. We've seen all the data
- structures used by AmigaDOS and have had a chance to modify a block.
- There are a number of implications of AmigaDOS structure that this
- document hasn't covered, but these things will become apparent as you
- are given the opportunity to apply the disk editor.
-
- I hope the information forwarded by this document will help you solve
- or at least understand problems that may occur from time to time when
- storing things on AmigaDOS compatible devices.
-
- A Trouble-shooting Example
- --------------------------
- This information was recently invaluable to me as I discovered a
- problem with my hard drive recently that could have blossomed into a
- fairly major disaster. A file was written on top of another file.
-
- I kept getting a read/write error when I tried to copy the
- over-written file to another device. So, I examined the hard drive
- with Sectorama. I used the hash function to locate which hash chain
- the file was stored under, traversed the hash chain until I found the
- file header block of the file in question. I then traversed the list
- of data blocks for the file by hitting the d key repeatedly. The
- list seemed to be intact since I was able to follow the list to its
- last block.
-
- I then hit the h key to display the file header block again. It
- was the file header block of an entirely different file! So, I jump
- back to the root, jumped to the file I was originally investigating,
- and again traversed the data block list while watching the value
- beside H-Go Header for any changes. About half-way through the file
- the value changed. I noted the block number of that data block,
- hit the h key to jump to the wrong file header block again, and noted
- that the block number of the erroneous data block was listed. I went
- back to the root block and back to the original file header block and
- found that the same erroneous data block was listed here, too.
-
- I checked all the files on the hard disk, and found that only one
- file was unreadable. Thus, that file had been overwritten. This
- implied that somehow the bitmap of the disk was erroneous since the
- data block used by the file was claimed by another file. I had to
- backup-up new files, format the hard drive to prevent further calamity,
- and copy back all the files. That cured the whole problem.
-
- I had a directory problem a while ago that I now know how to fix
- recover from with a disk editor. The directory of a device wrapped
- around so that when I executed a list command, I got an endless
- repetition of the same files, while other files on the disk would
- never be listed. When I listed the ignored files by naming them
- directly, they would show up. If I executed a dir command, the
- storage device was searched and searched and searched until the
- computer crashed. I believe that is due to dir's method of collecting
- all files in a directory for sorting until the end of the directory
- is reached, which, in this case, it never did.
-
- Solving this is a matter of copying all files possible to another
- device. This means individually copying all the files since wildcards
- cause a directory search which, in this case, would never end. The
- files you cannot see can be searched-out with Sectorama using wildcards
- since Sectorama provides full-disk searches without consulting a
- directory. After finding and copying all your files to another device,
- I'd recommend formatting the device to remove anything that might cause
- a relapse of the problem.
-
-
- If you have any corrections, comments, or suggestions about the above
- document, please send them to me or tell me about them. You can reach me at:
-
- //
- \X/ Tesseract BBS
- (306)757-5699
- (24 hours, 8N1, 300 or 1200 baud)
-
- address: Dwayne Miller
- 770 Robinson Street
- Regina, Saskatchewan, Canada (Yup, way up there!)
- S4T 2M1
-
- voice: (306)525-1652
-
- P.S. Sectorama was written by David Joiner of MicroIllusions and is commonly
- available, often named 'sec.arc' or 'sector.arc' or 'sectoram.arc' etc.
-