In article <1992May2.020223.24...@cs.brown.edu> w...@cs.brown.edu (Wen-Chun Ni) writes:
>In article <1992Apr30.172545.27...@cs.umu.se> dvl...@pippin.cs.umu.se (Daniel Brahneborg) writes:
>>I heard something a while ago about some program that could
>>repartition your hard disk without deleting everything on it,
>>but just writing a new smaller FAT. Of course the files had to
>>be on the lower part of the disk. As I have ~160 megs on my HD,
>I want it too, please. I've tried partit and edpart, but they all
>have their limitations.
It's not a program, but a manual procedure requiring
a. a partitioning program
b. a sector editor
Here it is :
Reformatting your hard disk, and reinstalling all your DOS programs from
scratch can be a real nuissance, and is unecessary.
Breathe a sigh of relief : it is possible to non-destructively repartition
hard disks.
Notes : Before continuing, make sure you have a RECENT BACKUP.
I assume that you understand hex arithmatic, and are not
afraid of a little assembler or DEBUG.
Actually, a decent partition and disk editor will get you around
this - NU works gret.
Of course, the modern programmer doesn't use anything but a
source level debugger - so I've included some helpful hints
and the command syntaxes. However, there is no room for
handholding here : if you screw up, you might have to use
that backup. Don't do it unless you are confident in your
abilities.
Also, this procedure only works with NON-EXTENDED DOS partitions,
< 64K logical sectors, (DOS 4 large partitions add additional BPB
fields that I am unsure of - roughly the same procedure applies there
though. According to Townsend' Advanced MS DOS : Expert Techniques
for programmers
offset 26h will have the signature byte 29h if this is
the case, 20h a dword containing the number of sectors if
volume size > 64K sectors
I still use MS-Loss 3.3, with an ~82M partition under disk mangler
and fall into the tested category)
Large partitions, handled by a third party partition manager
and handled so that there are < 64K logical sectors
work - this was the case with my SCSI disk.
I will lay down what general procedures you need to know (
required to read / write the raw disk), as well as the
data structures we are dealing with. Then I will proceed
with the entire procedure, which applies the general procedures
in reading and modifying the data structures. If it looks like
a tech manual - it is. If you don't grok non-destructive
repartitioning, you shouldn't be doing it.
DEBUG has a Hexaritmatic command, h which will add and
subtract the two operands. You may find this useful.
IE : I have loaded sector 0 into memory at 0200, and wish to know
the address of the partition table at 1be.
-h 200 1be
03BE 0042
Where 03BE is the sum, and 042 the difference.
DEBUG prints a segment before the offset : note that your segments
will probably not match. The offset is what's important.
The 80x86 family is LITTLE ENDIAN. This means least significant
byte first - ie the internal representation of 0x12345678 would be
78 56 34 12. When dealing with multi-byte quantities, keep this
in mind.
When I say word, I mean word as in the Intel documentation :
16 bits. dword is 32 bits.
DISK BIOS addresses cylinder, head as zero based, sector
as 1 based. Same thing for the partition table.
DOS addresses sectors as 0 based, from the start of the
logical partition, and as logical sectors which may
consist of multiple physical sectors.
Unless otherwise noted, all numbers are hex.
You're better off using Norton Utilities - but Debug works fine
too.
This document is sort of a quick hack 8^)
Tools :
Required : DEBUG, and a disk defragmenter
Optional : partition editors (NOTE!!!! Make sure these DO NOT perform
any formatting, and allow you to edit partitions in the
REAL order they appear on the disk.), the Linux FDISK program,
utilities that save an image of the boot sector FATs, and
directory (IE Norton's Format Recover), a raw disk editor
(Norton Utilities NU)..
Procedures :
Editing memory with debug :
d ADDRESS l LENGTH
will dump memory
f ADDRESS l LENGTH values
will fill memory.
Reading and writing DOS logical sectors (using debug):
Reading is accomplished using the debug l command.
l ADDRESS DRIVE SECTOR COUNT
Where ADDRESS is the hex address of where to put the data,
DRIVE is a 0 based drive number (IE A:=0, B:=1, C:=2, etc. If there
is only one floppy drive, it is considered both A: and B: as it is
in DOS)
SECTOR is a zero based sector number. Of interest to us are
sector 0, the boot sector, and the sectors immediately following it -
the FAT's.
COUNT is the number of sectors to read.
So, to read in the first 10 sectors of the FAT on my E: partition (the
FAT starts at sector 1), storing them at 0200, I would enter
l 0200 4 0 A
Writing is done with the W command, which takes the same
parameters. Assuming I had edited the boot sector of E: at 0200 in memory,
and wanted to write it back to disk, I would type in
w 0200 4 0 1
Using Norton Utilities NU:
<E>xplore disk, <C>hoose Item, <S>ector, <E>dit/display
Unfortunately, absolute sector 0 falls outside of all partitions (this
is where the partition table is), and we need to use a different
procedure for it.
Reading / Writing absolute sector 0:
The following debug / assembler interaction shows how to read absolute disk
sector 0 , replace xx with 80 for hard disk 0, 81 for hard disk 1:
-a 0100
1984:0100 mov ax, 0201
1984:0103 mov bx, 0200
1984:0106 mov cx, 0001
1984:0109 mov dx, 00xx
1984:010C int 13
1984:010E int 20
1984:0110 ^C
-
-g = 0100
This will read sector 0 into DS:0200. To write it back,
-a 0100
1984:0100 mov ax, 0301 <RETURN>
1984:0103 ^C
-g = 0100.
Using Norton Utilities NU :
Under <E>xplore disk, choose <C>hoose item, <A>bsolute sector, <E>dit / display
Structures :
1. The Partition table
The partition table resides at absolute sector 0 (ie
cylinder 0, head 0, sector 1) on all harddisks. It is accessed
by a short bootstrap loader on that sector, which reads the partition
table and then picks a partition from which to load the boot sector for
the operating system.
The partition table itself resides at offset 1be. It is 64 bytes (decimal)
in length, plus the two byte signature 55 AA. When dealing with the
partition table, make sure byte 40 (offset 1fe of the sector) is 55 and
byte 41 (offset 1ff of the sector) is
of the sector
The partition table is subdivided into FOUR 16 byte entries, fielded
as follows :
offset length field
0 byte bootable 80h = bootable, 0 = not
1 byte starting head number
2 word starting cylinder (and sector - sector is 1 based
high byte is low byte of cylinder, low byte low 6 bits is
sector, high 2 bits of low byte high 2 bits of cylinder)
typically, sector = 0.
4 byte system 1 = primary DOS, 12 bit, 4 = primary DOS 16 bit,
5 = extended DOS, 8 = NON-DOS (might be usable)
5 byte ending head number
6 word ending cylinder / sector
8 dword starting sector (relative to begining of disk - THIS IS ZERO
based)
C dword number of sectors
My partition table on drive 0 looks like :
-d 3be
1984:03BE 80 01 ..
1984:03C0 01 00 01 05 22 08 22 00-00 00 0A 07 00 00 00 00 ....".".........
1984:03D0 01 09 51 05 E2 2B 2C 07-00 00 E4 7F 02 00 00 00 ..Q.b+,...d.....
1984:03E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1984:03F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U*
Interpreting this, we can see that I have two partitions in use -
partition 1 and 2, the rest being blank.
My first partition is bootable (80)
FAT size is 12 bits (type = 01)
It starts at head 1, cylinder 0, sector 1, which is sector 22
(34 decimal) relative to the start of the disk.
It is 0000070a sectors in length (1802 decimal), and ends on
head 5, cylinder 8, sector 22 (34 decimal).
My second partition is non-bootable (00).
It is type 51 (Disk Mangler) meaning I need to
find out fat size some other way.
It starts at Head 0, cylinder 9, sector 1, which is sector 72c
(1836 decimal) relative to the start of the disk.
It is 27FE4 (163812 decimal) sectors in length, and ends on
head 5, cylinder 32b (811 decimal), sector 22 (34 decimal)..
See how I got ending cylinder? In Hex, each digit is a nibble. You can
easily convert to binary a nibble at a time. IE E2 becomes 1110 0010
The low 6 bits (sector) are 10 0010 = 22
The high 2 bits are 11 = 3
So high byte cylinder is 03, low byte is 2B so cylinder = 032b
Got it?
2. The Boot sector
The second important piece of data is the bootsector. There are a number
of fields we are interested in. I have ommitted the DOS 5 extended fields
(Can't give you an answer I'm 100% sure on), as well as fields unecessary
to our procedure.
Fields we are interested in :
Offset Size Field
b word bytes per LOGICAL sector - divide by 512 to get physical
to logical mapping
d byte sectors per cluster. Multiply by logical sector size and
divide by 1024 (decimal) to get K / cluster
13 word total number of LOGICAL sectors. This is one field
extended by DOS5.
18 word sectors per
...
read more »