How to rename the volume label of partition
In this post, I write about my first writing experience on the hard disk using
the INT 13H.
This one is the last post of a series which began with
"Learning how to write on the hard disk with INT 13H"
and finds here the conclusion where you can read about the development of the
final procedure volume_rename.
Let me say that, after all the learning and the training done with the other
posts until here, it is now time to go back to school and pass the exam, which
consists in renaming the volume label of the hard disk.
The design phase
I prepared for you the file "volume_rename.npp" in the DOWNLOAD AREA so that you can read the program and build it for yourself, meanwhile in the post, I would like to describe the logic with the use of the flow charts.
Fig. A - Memory organization of volume_rename |
In Fig. A you can see the memory organization of volume_rename which is similar to the one of the space shuttle (see Fig. A of the post "Design and build the space shuttle") except for the fact that I decided to dedicate considerably less RAM space for the read/write buffer. I decided to add this extra complication in order to enhance my learning experience. In the case of the space shuttle, I used a read/write buffer in RAM that was big enough to contain the ROOT directory all at once, but I wanted to learn how to handle a buffer in RAM that was smaller than the total block of data (the ROOT folder in this case) that I wanted to examine. The first problem that I considered was the determination of the best size for the RAM buffer when I had to read from and write to the hard disk. I realized that INT 13H reads and writes crunches of data of certain size (bytes per logic block, or bytes per sector: BPB_BytsPerSec) so my smallest RAM buffer had to be at least as big as the biggest BPB_BytsPerSec1. Then I considered another important crunch of data: the cluster. A cluster is a group of consecutive sectors (or logic blocks) that can be up to 32 KBytes big. Had I to reserve a RAM buffer as big as the largest cluster? I thought that it was not necessary. The cluster was (and is) an artificial grouping created by the file system and I didn't have to read a cluster all at once because I could have read portions of it. The same is not true for the size of the logic block (or sector: BPB_BytsPerSec) which depends on the real hardware and it has to be accessed all at once. My conclusion was that the minimum RAM buffer for reading and writing operations had to be at least as big as the largest logic block (or sector): 4096 Bytes.
Fig. B - Full overview of volume_rename |
In
Fig. B, I present you the full overview of the program volume_rename. On the
top left corner, you find the entry point immediately followed by the exit
sequence of the procedure. These two components are one after the other in the
address space. The program goes from the entry point to the central block with
a right and downward arrow. I used such graphic symbolism to indicate that the
jump goes toward higher address in memory from where it comes. Instead, I
used left and upward arrows to symbolize the jumps that go backwards in memory
from where they come.
The central block of the program reads the ROOT directory in RAM and scans it
looking for the original volume label: the one that I want to rename. This
part of the program is more complex than strictly required because I wanted to
experiment and learn how to read a ROOT folder using a RAM buffer which was
smaller than the ROOT.
The last block, in the bottom right corner, does the actual job.
Fig. C - Scan ROOT |
In
Fig. C, I present you the central block that scans the ROOT looking for the volume
label entry. In the beginning, I calculated how many logic blocks were fitting
inside the buffer in RAM (BUFF_SIZE_BLK =
4096 / BPB_BytsPerSec). Then I computed the Logic Block Address
(LBA) of the beginning of ROOT on the disk (LBA_RW_START). I took the source
values for the calculation from the BIOS Parameter Block (BPB) that I knew was
still in RAM embedded in the space shuttle relocated at address 0x07A00. I
didn't blindly take the values from the BPB in RAM, but I supposed that
something could have been wrong, so I performed plausibility check on the read
values before using them for the computation of BUFF_SIZE_BLK and
LBA_RW_START. For that case, I prepared the first error detection and exit
condition.
If everything was ok, the program continued and set the total number of
entries in the ROOT directory (ROOT_Entries_Count), which I used to detect the
end of the ROOT. Immediately after this block, the program entered the loop
used for the search of the volume label. Looking carefully, you will recognize
that I searched the volume label using two nested loops: the outer one took
care of updating the portion of ROOT in RAM; the inner one took care of the
actual search.
Fig. D - User interface and rename |
In
Fig. D, you see the last part of the program. I decided to display the label of the
volume found and ask the user if he/she wanted to proceed with the rename. I
thought that in case I did something wrong in the program and the same had
detected something different from the volume label (false detection), it was a
good idea to let display on screen what volume_rename had actually
found before renaming it. Suppose that it was a false detection, then probably
some of the eleven bytes were not displayable on the screen as ASCII. For this
reason, I programmed a replacement of any bytes outside the displayable range
of the standard ASCII2
with the character "?" and, at the same time, I displayed the hexadecimal
version of the string in addition to the ASCII one.
In my intention, this had to work as the last checkpoint before writing on the
hard disk. When I decided which symbols to use for the user feedback, I
imagined to use "Y" and "N", but I immediately realized that I had a german
keyboard layout (where "Y" and "Z" are swapped compared to the US layout) and,
probably, the BIOS had a US layout so the use of letters was not good.
Thinking of a general approach, I considered that the numbers are the only
keys that are probably always the same on any keyboard layout, so I decided to
rely on numbers rather than on letters and I used "0" and "1" for my simple
user feedback.
The manufacturing phase
According to my opinion, everything we humans create goes thru three steps: born of an idea (or design phase), realization of that idea (or manufacturing phase) and finally check that the realized implementation behaves as expected when it was just an idea in our mind (test phase). Creation of software is no different. I have shown you already the design phase in the previous paragraph but I am not going to show you the manufacturing phase in the post. Instead of that, I uploaded the file "volume_rename.npp" in the DOWNLOAD AREA in such a way that you can also practice with your manupfacturing phase, rather than just reading in the post about my manufacturing phase. However, I decided to have this paragraph here in the post just to make it clear that this phase does exist even if I didn't described it in all details.
The test phase
Fig. E - Original volume label before rename |
In Fig. E, you see that I started with the volume label equal to "TEST".
Fig. F - Detection of volume label and exit w/o rename |
In Fig. F, you see that volume_rename detected the volume label correctly and I pressed "0" to exit without renaming. After that I rebooted and I wanted to rename but it didn't go as I originally expected.
Fig. G - Write error |
In Fig. G, you see the write error that occurred when I called RW_LBA. I originally developed RW_LBA to be a torchlight helping me if any problem occurred and indeed it accomplished what I designed it for. Reading the message on the screen, I had an indication that the function call with AX = 0x4302 was probably not supported and, in fact, looking again in the "Ralf Brown Interrupt List" (Fig. H) I knew that the write with verifying was definitively not supported by the BIOS of my IBM T413.
Fig. H - Extract from the Ralf Brown Interrupt List |
Once I understood that I hadn't any write with verify, I changed the RW_LBA to make it use a simple write (AX = 0x4300).
Fig. I - RW_LBA returns an invalid function call |
In Fig. I, you see that I forgot to change the call that volume_rename made to RW_LBA, and I got back on screen the proper error message telling me where the problem was. Once more, I was happy with the way RW_LBA was helping me during the test of volume_rename.
Fig. J - Rename attempt |
After fixing all the details again (or at least I thought that I did it for all the details...) I run volume_rename and I got the feedback on the screen telling me that everything was ok (Fig. J). You can imagine, how much I was surprised to reboot in Windows XP and see again the same situation as in Fig. E. I scratched my head and I triple checked the program until I found the problem. I have already mentioned how painful it was to develop programs directly in DEBUG.EXE: every time I needed to do just a small adjustment in the code, this was immediately resulting in some shift (usually one up to tree bytes) in address space that forced me to control all addresses every time from the beginning to the end of the program. When I adjusted the code introducing the changes mentioned before, I controlled all addresses, but I missed one small address fix. The consequence was that the program wrote the string "GOOD RENAME" outside the RAM buffer so that once INT 13H wrote the RAM buffer back on the hard disk, it was exactly unchanged.
Fig. K - GOOD RENAME from within Windows XP |
In the end, I made it to rename the volume label of my partition using the INT 13H for writing on the hard disk. I was really happy, once I saw it in windows XP (Fig. K) and I wanted to double-check it with volume_rename again (Fig. L).
Fig. L - GOOD RENAME from within volume_rename |
I hope that you have found my experience, written in this post, somehow helpful for you, in which case I would be very happy for the help I may have given. Talking about me, I was happy because this was again a small step but in the right direction for my self-learning journey.
Comments
Post a Comment