Published by +Tsehp March 2000
Courtesy of Immortal-Descendants
Do not read this or attempt to apply the concepts reported in this essay if you fit into any of these categories;
Well now that I have warned you I probably ought to explain what this essay is about. As I have used computers more and more I have become familiar with them, even accustomed, now I know what ails them and how to cure it. And so onto the ailment, a knackered hard disk, and not just any knackered hard disk, one who's mbr record has been messed up. Their seems to be a lot of solutions for if you accidentally format you hard disk or delete your work (unless it was valuable of course), there are however no real ways of fixing the even lower level problem of boot records on large hard disks, or at least not that I have come accross. What happens if you manage to leave your MBR in an inconsistent state after using Fdisk or Partion Magic? The likely hood is they won't want to associate themselves with it ever again, after all who likes to admit their failures? Well I will attempt to explain how to fix some of these problems and just what is wrong in some cases as I have still yet to fix them myself.
I would also like to note that although all the misadventures with my hard disks happened when some-one was attempting to use partion magic and/or install linux I hold no grudges against them, in fact both products are highly valued by me, I love the safety that partion magic allows. Being able to see what you are doing and do all the neat things like moving partitions is great, I have never had a problem with it my self and I don't know how it is possible to mess up using it. I also like linux, I have 95 for games, and presently for DVD's, and Linux for work - it's the bussiness.
A brief explanation of the structure of modern hard disks
Since hard disks have become so large and IDE and the original file-systems like FAT were not designed for HD's this large a solution had to be found to allow the Hard Disks to be accessed while not making all the existing software obsolete. The way that hard disks have always been accessed by operating systems has always been through int 13h on intel architectures. If you have a look at the functions for disk access they take 3 bytes to specify the sector to read/modify. Head/sector/track - 3 bytes gives a range of 0 - 16777215 sectors, with each sector holding 512 bytes this allows 8589934080 bytes, or 388607.5k - 8191Mb - 7.9Gb.
|Now I didn't do this arithemetic originally, I hadn't really thought about this limitation despite having 10Gb Hd's in my machine. If you start off using the standard int 13 calls to read the boot sector then you will get the boot sector for your C drive, expecting a Master Boot Record alarm bells started ringing. How the hell do I access my MBR if int 13 doesn't work? At this point I figured the best way to find out was to look at something that must be able to access it - fdisk. After unpacking it I dissasembled and just had a look through the source, I didn't know where to look so I started looking for familiar signs. Starting with a search of int 13h I noticed a call to a function 41h, I didn't recognise this so I had a look in the interrupt list.|
Int 13h - function 41h turns out to be a check for the int 13 extensions, The
next functions are the actual extended read and write functions, they allow the
access of large hard disks. The original int 13 calls seem to be
overriden by the os and made to access the partitions as if they were individual
hard disks while these extended functions are the genuine article, providing the
real read and write capability.
Now I've explained how we actually find the real hard disk under all confusion, the way that hard disks are partioned would be useful. Each hard disk has a Master Boot Record. This is the sector that is loaded by the BIOS when the machine starts up, just as the boot sectors of disks always have been, it's just that the MBR looks for another boot sector to load. Their should be one primary partition where the primary operating system will probably be located. After that there will be extended boot sectors referencing other boot sectors. The structure is like a tree, with actual boot sectors of the partitions as the leaves and the extended boot sectors as the branches, each allowing up to 4 way branches.
I have pasted in the structure of the boot sectors from the interrupt list, I don't think I can put it any better. I have abbreviated the operating system indicator to the most common o/s's.
Format of hard disk master boot sector: Offset Size Description (Table 00650) 00h 446 BYTEs Master bootstrap loader code 1BEh 16 BYTEs partition record for partition 1 (see #00651) 1CEh 16 BYTEs partition record for partition 2 1DEh 16 BYTEs partition record for partition 3 1EEh 16 BYTEs partition record for partition 4 1FEh WORD signature, AA55h indicates valid boot block Format of partition record: Offset Size Description (Table 00651) 00h BYTE boot indicator (80h = active partition) 01h BYTE partition start head 02h BYTE partition start sector (bits 0-5) 03h BYTE partition start track (bits 8,9 in bits 6,7 of sector) 04h BYTE operating system indicator (see #00652) 05h BYTE partition end head 06h BYTE partition end sector (bits 0-5) 07h BYTE partition end track (bits 8,9 in bits 6,7 of sector) 08h DWORD sectors preceding partition 0Ch DWORD length of partition in sectors SeeAlso: #00650 (Table 00652) Values for operating system indicator: 00h empty partition-table entry 01h DOS 12-bit FAT 04h DOS 16-bit FAT (up to 32M) 05h DOS 3.3+ extended partition 06h DOS 3.31+ Large File System (16-bit FAT, over 32M) 07h OS/2 HPFS 07h Windows NT NTFS 08h OS/2 (v1.0-1.3 only) 82h Linux Swap partition 83h Linux native file system (ext2fs/xiafs)
Now we know what the boot record should look like, and we know how to read it we should be able to do just that. There is also a problem with the information in the MBR, it would appear that when they designed MBR's it was also pre large hard disks. There are again only 3 bytes for the sector again. According to the messages generated by Partion Info these are filled with place holders, the main problem is I'm not sure where it is figuring out the real values from. The 'sectors preceding partition' does however allow us to figure out where the partition is, so it shouldn't matter too much so long as you don't need to actually create a new partition by hand.
Just grab the noddy readMb program from the bottom of this page if you can't be bothered to create your own. Load the MBR and have a look at it in your fave hex viewer (UE does it for me). The first partition record entry should be okay, that is the one for your primary partition and should have the boot indicator set, it will probably be one of the other records that is screwed up. If you did manage to find a copy of partition info, it is freely distirbutable after all, then run that. Partion Info will help to collaborate the information you should be seeing in your mbr. The other program at the end of the essay is to write an MBR, use it with extreme caution. I would recommend you only keep the source on your hard disk and don't leave the executable lying around, it shouldn't work while an os is up but I shouldn't risk it. Remember to create a back up of the sector you are going to change before you do. If you haven't made the correct change you should at least be able to return the system back to it's previous state by just re-writing the old sector back. In order to run the program you will need a DOS boot up disk (just creating a system disk from 95 will do). Copy the program over and the sector to write and then reboot. Run the program and that is it.
Solving problem 1 - boot record in an inconsistent state.
When Partion Magic left the hard disk in an inconsistent state all that it did was leave a garbage entry in the MBR. All that I did was looked at the MBR and remove the offending entry, blanking it out with 0's. Save the new sector and write the sector to the hard disk, it's as simple as that.
Solving problem 2 - LILO boot sectors gone when partition reformatted to
This one isn't quite as simple, you need to get hold of an already working MBR from something like 95. Then all you need to do is merge the code from the working MBR with the data from your MBR.
|If you dissasemble your sector you will see that the start is all code. In the case of a 95 mbr it just looks through the partion records for a record with the boot indicator and loads that boot sector into memory and executes it. Linux on the other hand loads in about 5 sectors from it's partition and executes them, this allows all the extra 'multi-boot' functionality of the LILO loader, it was also why my HD no longer booted.|
Here is a sample from my HD, I have messed up sector data at the bottom although you should be able to see the basic structure and possibly even use this as the template for what you use for recovering your own HD.
0000 33 C0 8E D0 BC 00 7C FB-50 07 50 1F FC BE 1B 7C 0010 BF 1B 06 50 57 B9 E5 01-F3 A4 CB BE BE 07 B1 04 0020 38 2C 7C 09 75 15 83 C6-10 E2 F5 CD 18 8B 14 8B 0030 EE 83 C6 10 49 74 16 38-2C 74 F6 BE 10 07 4E AC 0040 3C 00 74 FA BB 07 00 B4-0E CD 10 EB F2 89 46 25 0050 96 8A 46 04 B4 06 3C 0E-74 11 B4 0B 3C 0C 74 05 0060 3A C4 75 2B 40 C6 46 25-06 75 24 BB AA 55 50 B4 0070 41 CD 13 58 72 16 81 FB-55 AA 75 10 F6 C1 01 74 0080 0B 8A E0 88 56 24 C7 06-A1 06 EB 1E 88 66 04 BF 0090 0A 00 B8 01 02 8B DC 33-C9 83 FF 05 7F 03 8B 4E 00A0 25 03 4E 02 CD 13 72 29-BE 46 07 81 3E FE 7D 55 00B0 AA 74 5A 83 EF 05 7F DA-85 F6 75 83 BE 27 07 EB 00C0 8A 98 91 52 99 03 46 08-13 56 0A E8 12 00 5A EB 00D0 D5 4F 74 E4 33 C0 CD 13-EB B8 00 00 80 30 29 11 00E0 56 33 F6 56 56 52 50 06-53 51 BE 10 00 56 8B F4 00F0 50 52 B8 00 42 8A 56 24-CD 13 5A 58 8D 64 10 72 0100 0A 40 75 01 42 80 C7 02-E2 F7 F8 5E C3 EB 74 49 0110 6E 76 61 6C 69 64 20 70-61 72 74 69 74 69 6F 6E 0120 20 74 61 62 6C 65 00 45-72 72 6F 72 20 6C 6F 61 0130 64 69 6E 67 20 6F 70 65-72 61 74 69 6E 67 20 73 0140 79 73 74 65 6D 00 4D 69-73 73 69 6E 67 20 6F 70 0150 65 72 61 74 69 6E 67 20-73 79 73 74 65 6D 00 00 ; I think you should be able to cut here, you then take ; the data from your hd and place it at the bottom. 0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 0180 00 00 00 8B FC 1E 57 8B-F5 CB 00 00 00 00 00 00 0190 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 01A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 01B0 00 00 00 00 00 00 00 00-25 1D 50 F0 00 00 80 01 ; the first partition record starts here at the 80 01C0 01 00 06 7F 7F 7A 3F 00-00 00 __ __ __ 00 00 00 01D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 01E0 __ __ 05 7F FF __ __ __-__ 00 00 __ __ 00 00 00 01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA
I'm afraid I've forgotten the exact cut off point but you should be able to figure that out reasonably by trial and error or by checking out the code of the sector. The bits that I have blanked are definately not important to you, I just don't really want any more information about my HD out there than needs to be.
Solving problem 3 - Deleted partitions
This should be possible, I still haven't gotten around to figuring it out though. The basic principle is similar to undeleting files, no program deletes anything anymore than it has to. Dos FDisk certainly just removes the entry from the referencing partition record. If you delete your overall extended partition then only your MBR will be altered - the actual partion record for the extended partion record will still be there completely unaltered. In order to 'undelete' the partition all you need to do is put the entry back in, this is dead easy if you know all the values for the partion record, if you don't then you are in the same situation as me. I still haven't gotten around to figuring out what to put there. The boot and os indicators are simple, it's just all the stuff for head/track/cylinder and the other stuff. While I know about the place holders I haven't figured out how to get all the information to put in the MBR for the real info. There are a couple of approaches to figuring this out that I have thought of;
;---- readMB.asm ---- jmp start noExtension db 'Int 13 extensions not found',10,13,'$' sector db 512 dup (0) extensions db 'Int 13 extensions found',10,13,'$' cannotRead db 'Error reading boot sector',10,13,'$' fileName db 'sector.dat',0 ; disk address packet ;;;;;; diskAddressPacket db 10h db 0 blocksToTransfer dw 0 transferBuffer dd 0 startblock db 8 dup (0) ;;;;;;;;;;;;;;;;;;;;;;;;;;;; start: ; int 13 extensions - installation check mov ah,41h mov bx,55aah mov dl,80h int 13h jc extensionsNotAvail ; bx should be aa55h if installed cmp bx,0aa55h jnz extensionsNotAvail ; just tell user that they are found and we are proceeding mov ah,9 mov dx,offset extensions int 21h ; set up the address packet mov blocksToTransfer,1 mov ax,cs mov [offset transferBuffer+2], ax mov dx,offset sector mov [offset transferBuffer], dx ; extended read mov ah,42h mov dl,80h mov si,offset diskAddressPacket int 13h jc errorReading ; create file sector.dat mov ah,3ch mov dx,offset fileName mov cx,0 int 21h ; write the sector to it mov bx,ax mov dx,offset sector mov cx,512 mov ah,40h int 21h ; close it mov ah,3eh int 21h ; exit mov ax,4c00h int 21h extensionsNotAvail: mov ah,9 mov dx,offset noExtension int 21h mov ax,4c01h int 21h errorReading: mov ah,9 mov dx,offset cannotRead int 21h mov ax,4c01h int 21h ; --- writeMB.asm --- jmp start noExtension db 'Int 13 extensions not found',10,13,'$' sector db 512 dup (0) extensions db 'Int 13 extensions found',10,13,'$' cannotRead db 'Error reading boot sector',10,13,'$' fileName db 'new.mbs',0 ; disk address packet ;;;;;; diskAddressPacket db 10h db 0 blocksToTransfer dw 0 transferBuffer dd 0 startblock db 8 dup (0) ;;;;;;;;;;;;;;;;;;;;;;;;;;;; start: ; int 13 extensions - installation check mov ah,41h mov bx,55aah mov dl,81h int 13h jc extensionsNotAvail ; bx should be aa55h if installed cmp bx,0aa55h jnz extensionsNotAvail ; just tell user that they are found and we are proceeding mov ah,9 mov dx,offset extensions int 21h ; open file new.mbs (read only) mov ax,3d00h mov dx,offset fileName mov cx,0 int 21h ; write the sector to it mov bx,ax mov dx,offset sector mov cx,512 mov ah,3fh int 21h ; close it mov ah,3eh int 21h ; set up the address packet mov blocksToTransfer,1 mov ax,cs mov [offset transferBuffer+2], ax mov dx,offset sector mov [offset transferBuffer], dx ; extended read mov ah,43h mov al,0 mov dl,81h mov si,offset diskAddressPacket int 13h jc errorReading ; exit mov ax,4c00h int 21h extensionsNotAvail: mov ah,9 mov dx,offset noExtension int 21h mov ax,4c01h int 21h errorReading: mov ah,9 mov dx,offset cannotRead int 21h mov ax,4c01h int 21h ; ---- the end.
Comments and suggestions can be emailed to me at firstname.lastname@example.org