2 Copyright © 2003-2006, The AROS Development Team. All rights reserved.
6 #include <utility/tagitem.h>
7 #include <libraries/partition.h>
8 #include <devices/trackdisk.h>
9 #include <proto/exec.h>
10 #include <proto/dos.h>
11 #include <proto/partition.h>
18 #include <aros/debug.h>
23 /*** Prototypes *************************************************************/
24 struct PartitionHandle
*CreateRootTable(CONST_STRPTR device
, LONG unit
);
25 struct PartitionHandle
*CreateMBRPartition(struct PartitionHandle
*parent
, ULONG lowcyl
, ULONG highcyl
);
26 struct PartitionHandle
*CreateRDBPartition(struct PartitionHandle
*parent
, ULONG lowcyl
, ULONG highcyl
, CONST_STRPTR name
, BOOL bootable
);
28 /*** Functions **************************************************************/
31 struct PartitionHandle
*root
= NULL
;
38 PrintFault(IoErr(), NULL
);
42 device
= (CONST_STRPTR
) ARG(DEVICE
);
43 unit
= *(LONG
*)ARG(UNIT
);
45 D(bug("[C:Partition] Using %s, unit %d\n", device
, unit
));
47 if (ARG(QUIET
) && !ARG(FORCE
))
49 PutStr("ERROR: Cannot specify QUIET without FORCE.\n");
55 Printf("About to partition %s unit %d.\n", device
, unit
);
56 Printf("This will DESTROY ALL DATA on the drive!\n");
57 Printf("Are you sure? (y/N)"); Flush(Output());
59 Read(Input(), &choice
, 1);
66 if (choice
!= 'y' && choice
!= 'Y') return RETURN_OK
;
70 Printf("Partitioning drive...");
74 D(bug("[C:Partition] Partitioning drive...\n"));
76 if ((root
= CreateRootTable(device
, unit
)) != NULL
)
78 CONST ULONG TABLESIZE
= 5 * 1024 * 1024;
79 CONST ULONG DH0SIZE
= 1 * 1024 * 1024;
80 struct DriveGeometry rootDG
= {0};
81 ULONG rootSize
; /* Size in kB */
83 GetPartitionAttrsTags(root
, PT_GEOMETRY
, (IPTR
) &rootDG
, TAG_DONE
);
84 rootSize
= (rootDG
.dg_TotalSectors
/ 1024) * rootDG
.dg_SectorSize
;
86 /* See if the partition is 5 GB or larger */
87 if (rootSize
>= TABLESIZE
)
90 Only use the first 5 GB, first creating a 1 GB system
91 partition (DH0) and then a 4 GB user partition (DH1).
94 struct PartitionHandle
*mbrp
= NULL
, /* MBR partition */
95 *rdbp0
= NULL
, /* First RDB partition */
96 *rdbp1
= NULL
; /* Second RDB partition */
98 ULONG cylSize
= rootSize
/ rootDG
.dg_Cylinders
,
99 mbrhighcyl
= (TABLESIZE
/ cylSize
) - 1,
100 rdbp0highcyl
= (DH0SIZE
/ cylSize
) - 1,
101 rdbp1lowcyl
= rdbp0highcyl
+ 1,
104 /* Create a partition in the MBR table */
105 mbrp
= CreateMBRPartition(root
, 0, mbrhighcyl
);
107 /* Create RDB partition table inside MBR partition */
108 if (CreatePartitionTable(mbrp
, PHPTT_RDB
) != 0)
110 PutStr("*** ERROR: Creating partition table failed. Aborting.\n");
111 return RETURN_FAIL
; /* FIXME: take care of allocated resources... */
114 /* Create a partition in the RDB table */
115 rdbp0
= CreateRDBPartition(mbrp
, 0, rdbp0highcyl
, "DH0", TRUE
); // FIXME: error check
116 rdbp1highcyl
= mbrhighcyl
- mbrp
->de
.de_LowCyl
;
117 rdbp1
= CreateRDBPartition(mbrp
, rdbp1lowcyl
, rdbp1highcyl
, "DH1", FALSE
); // FIXME: error check
119 /* Save to disk and deallocate */
120 WritePartitionTable(mbrp
);
121 ClosePartitionTable(mbrp
);
126 Use the entire partition.
129 struct PartitionHandle
*mbrp
= NULL
, /* MBR partition */
130 *rdbp
= NULL
; /* RDB partition */
132 /* Create a partition in the MBR table */
133 mbrp
= CreateMBRPartition(root
, 0, 0);
135 /* Create RDB partition table inside MBR partition */
136 if (CreatePartitionTable(mbrp
, PHPTT_RDB
) != 0)
138 PutStr("*** ERROR: Creating partition table failed. Aborting.\n");
139 return RETURN_FAIL
; /* FIXME: take care of allocated resources... */
142 /* Create a partition in the RDB table */
143 rdbp
= CreateRDBPartition(mbrp
, 0, 0, "DH0", TRUE
); // FIXME: error check
145 /* Save to disk and deallocate */
146 WritePartitionTable(mbrp
);
147 ClosePartitionTable(mbrp
);
150 /* Save to disk and deallocate */
151 WritePartitionTable(root
);
152 ClosePartitionTable(root
);
153 CloseRootPartition(root
);
156 if (!ARG(QUIET
)) Printf("done\n");
161 struct PartitionHandle
*CreateRootTable(CONST_STRPTR device
, LONG unit
)
163 struct PartitionHandle
*root
;
165 if ((root
= OpenRootPartition(device
, unit
)) != NULL
)
167 /* Destroy the existing partitiontable, if any exists */
168 DestroyPartitionTable(root
);
170 /* Create a root MBR partition table */
171 if (CreatePartitionTable(root
, PHPTT_MBR
) != 0)
173 PutStr("*** ERROR: Creating partition table failed.\n");
174 CloseRootPartition(root
);
180 PutStr("*** Could not open root partition!\n");
186 struct PartitionHandle
*CreateMBRPartition
188 struct PartitionHandle
*parent
, ULONG lowcyl
, ULONG highcyl
191 struct DriveGeometry parentDG
= {0};
192 struct DosEnvec parentDE
= {0},
194 struct PartitionType type
= {{0x30}, 1}; /* AROS RDB */
195 struct PartitionHandle
*partition
;
197 GetPartitionAttrsTags
201 PT_DOSENVEC
, (IPTR
) &parentDE
,
202 PT_GEOMETRY
, (IPTR
) &parentDG
,
211 GetPartitionTableAttrsTags
213 parent
, PTT_RESERVED
, (IPTR
) &reserved
, TAG_DONE
216 lowcyl
= (reserved
- 1) /
217 (parentDG
.dg_Heads
* parentDG
.dg_TrackSectors
) + 1;
222 highcyl
= parentDE
.de_HighCyl
;
225 CopyMem(&parentDE
, &partitionDE
, sizeof(struct DosEnvec
));
227 partitionDE
.de_SizeBlock
= parentDG
.dg_SectorSize
>> 2;
228 partitionDE
.de_Reserved
= 2;
229 partitionDE
.de_HighCyl
= highcyl
;
230 partitionDE
.de_LowCyl
= lowcyl
;
232 partition
= AddPartitionTags
236 PT_DOSENVEC
, (IPTR
) &partitionDE
,
237 PT_TYPE
, (IPTR
) &type
,
247 struct PartitionHandle
*CreateRDBPartition
249 struct PartitionHandle
*parent
, ULONG lowcyl
, ULONG highcyl
,
250 CONST_STRPTR name
, BOOL bootable
253 struct DriveGeometry parentDG
= {0};
254 struct DosEnvec parentDE
= {0},
256 struct PartitionType type
= {"DOS\3", 4};
257 struct PartitionHandle
*partition
;
259 GetPartitionAttrsTags
263 PT_DOSENVEC
, (IPTR
) &parentDE
,
264 PT_GEOMETRY
, (IPTR
) &parentDG
,
273 GetPartitionTableAttrsTags
275 parent
, PTT_RESERVED
, (IPTR
) &reserved
, TAG_DONE
278 lowcyl
= (reserved
- 1)
279 / (parentDG
.dg_Heads
* parentDG
.dg_TrackSectors
) + 1;
284 highcyl
= parentDE
.de_HighCyl
- parentDE
.de_LowCyl
;
287 CopyMem(&parentDE
, &partitionDE
, sizeof(struct DosEnvec
));
289 partitionDE
.de_SizeBlock
= parentDG
.dg_SectorSize
>> 2;
290 partitionDE
.de_Surfaces
= parentDG
.dg_Heads
;
291 partitionDE
.de_BlocksPerTrack
= parentDG
.dg_TrackSectors
;
292 partitionDE
.de_BufMemType
= parentDG
.dg_BufMemType
;
293 partitionDE
.de_TableSize
= DE_DOSTYPE
;
294 partitionDE
.de_Reserved
= 2;
295 partitionDE
.de_HighCyl
= highcyl
;
296 partitionDE
.de_LowCyl
= lowcyl
;
297 partitionDE
.de_NumBuffers
= 100;
298 partitionDE
.de_MaxTransfer
= 0xFFFFFF;
299 partitionDE
.de_Mask
= 0xFFFFFFFE;
301 D(bug("[C:Partition] SizeBlock %d\n", partitionDE
.de_SizeBlock
));
302 D(bug("[C:Partition] Surfaces %d\n", partitionDE
.de_Surfaces
));
303 D(bug("[C:Partition] BlocksPerTrack %d\n", partitionDE
.de_BlocksPerTrack
));
304 D(bug("[C:Partition] BufMemType %d\n", partitionDE
.de_BufMemType
));
305 D(bug("[C:Partition] TableSize %d\n", partitionDE
.de_TableSize
));
306 D(bug("[C:Partition] Reserved %d\n", partitionDE
.de_Reserved
));
307 D(bug("[C:Partition] HighCyl %d\n", partitionDE
.de_HighCyl
));
308 D(bug("[C:Partition] LowCyl %d\n", partitionDE
.de_LowCyl
));
310 partition
= AddPartitionTags
314 PT_DOSENVEC
, (IPTR
) &partitionDE
,
315 PT_TYPE
, (IPTR
) &type
,
316 PT_NAME
, (IPTR
) name
,
317 PT_BOOTABLE
, bootable
,