#define DEV_FD0 0x200 /* Device number of /dev/fd0 */
#define DEV_C0D0 0x300 /* Device number of /dev/c0d0 */
-#define MIN_REGION_MB 80
+#define MIN_REGION_MB 180
#define MIN_REGION_SECTORS (1024*1024*MIN_REGION_MB/SECTOR_SIZE)
#define MAX_REGION_MB 4095
int existing[1 + NR_PARTITIONS];
unsigned long offset= 0, extbase= 0, extsize;
int submerged= 0;
-char sort_index[1 + NR_PARTITIONS];
+char sort_index[1 + NR_PARTITIONS], sort_order[1 + NR_PARTITIONS];
unsigned cylinders= 1, heads= 1, sectors= 1, secpcyl= 1;
unsigned alt_cyls= 1, alt_heads= 1, alt_secs= 1;
int precise= 0;
/* Let the sort_index array show the order partitions are sorted in. */
{
int i, j;
- int idx[1 + NR_PARTITIONS];
- for (i= 1; i <= NR_PARTITIONS; i++) idx[i]= i;
+ for (i= 1; i <= NR_PARTITIONS; i++) sort_order[i]= i;
for (i= 1; i <= NR_PARTITIONS; i++) {
for (j= 1; j <= NR_PARTITIONS-1; j++) {
- int sj= idx[j], sj1= idx[j+1];
+ int sj= sort_order[j], sj1= sort_order[j+1];
if (sortbase(&table[sj]) > sortbase(&table[sj1])) {
- idx[j]= sj1;
- idx[j+1]= sj;
+ sort_order[j]= sj1;
+ sort_order[j+1]= sj;
}
}
}
- for (i= 1; i <= NR_PARTITIONS; i++) sort_index[idx[i]]= i;
+ for (i= 1; i <= NR_PARTITIONS; i++) sort_index[sort_order[i]]= i;
}
void dos2chs(unsigned char *dos, unsigned *chs)
return r;
}
-int bigenough(region_t *reg)
-{
- int sectors;
- if(reg->used_part)
- sectors = reg->used_part->size;
- else
- sectors = reg->free_sec_last - reg->free_sec_start + 1;
-
- return sectors >= MIN_REGION_SECTORS;
-}
-
int cylinderalign(region_t *reg)
{
if(reg->used_part) {
reg->used_part->size -= extra;
}
if((reg->used_part->size+1) % secpcyl) {
- reg->used_part->size -= secpcyl - (reg->used_part->size % secpcyl);
+ reg->used_part->size -= secpcyl - ((reg->used_part->size + 1) % secpcyl);
}
return reg->used_part->size > 0;
}
/* Start is unaligned. Round up. */
reg->free_sec_start += secpcyl - (reg->free_sec_start % secpcyl);
}
- if(reg->free_sec_last % secpcyl) {
+ if((reg->free_sec_last+1) % secpcyl) {
/* End is unaligned. Round down. */
- reg->free_sec_last -= reg->free_sec_last % secpcyl;
+ reg->free_sec_last -= (reg->free_sec_last+1) % secpcyl;
}
/* Return nonzero if anything remains of the region after rounding. */
}
if(probing) {
- v = HZ/2;
+ v = 2*HZ;
ioctl(device, DIOCTIMEOUT, &v);
}
/* Create region data used in autopart mode. */
free_regions = used_regions = nr_regions = nr_partitions = 0;
for(si = 1; si <= NR_PARTITIONS; si++) {
- i = sort_index[si];
+ i = sort_order[si];
if(i < 1 || i > NR_PARTITIONS) {
printf("Sorry, something unexpected has happened (%d out of range).\n", i);
exit(1);
regions[nr_regions].free_sec_start = free_sec;
regions[nr_regions].free_sec_last = table[i].lowsec-1;
regions[nr_regions].used_part = NULL;
- if(cylinderalign(®ions[nr_regions]) &&
- bigenough(®ions[nr_regions])) {
+ if(cylinderalign(®ions[nr_regions])) {
nr_regions++;
free_regions++;
}
}
if(autopartmode && si > 1) {
- if(table[i].lowsec < table[sort_index[si-1]].lowsec ||
- table[i].lowsec < table[sort_index[si-1]].lowsec + table[sort_index[si-1]].size) {
+ if(table[i].lowsec < table[sort_order[si-1]].lowsec ||
+ table[i].lowsec < table[sort_order[si-1]].lowsec + table[sort_order[si-1]].size) {
printf("Sanity check failed - partitions overlap.\n"
"Please use expert mode to correct it.\n");
exit(1);
free_sec = table[i].lowsec+table[i].size;
nr_partitions++;
- if(bigenough(®ions[nr_regions])) {
- nr_regions++;
- used_regions++;
- }
+ nr_regions++;
+ used_regions++;
}
/* Special case: space after partitions. */
regions[nr_regions].free_sec_start = free_sec;
regions[nr_regions].free_sec_last = table[0].lowsec + table[0].size-1;
regions[nr_regions].used_part = NULL;
- if(cylinderalign(®ions[nr_regions]) &&
- bigenough(®ions[nr_regions])) {
+ if(cylinderalign(®ions[nr_regions])) {
nr_regions++;
free_regions++;
}
if (bootblock[510] != 0x55 || bootblock[511] != 0xAA) {
/* Invalid boot block, warn user. */
stat_start(1);
- printf("Warning: About to write a new table on %s",
+ if(!autopartmode) printf("Warning: About to write a new table on %s",
curdev->subname);
- if(autopartmode) printf("\n");
stat_end(5);
}
if (extbase != 0) {
char *
prettysizeprint(int kb)
{
- static char str[20];
+ int toosmall = 0;
+ static char str[200];
char unit = 'k';
+ if(MIN_REGION_SECTORS > kb*2)
+ toosmall = 1;
if(kb >= 5*1024) {
kb /= 1024;
unit = 'M';
unit = 'G';
}
}
- sprintf(str, "%d%cB", kb, unit);
+ sprintf(str, "%d%cB%s", kb, unit,
+ toosmall ? " - too small for MINIX" : "");
return str;
}
do {
reg = regions;
- printf("\nI've found the following region%s on this disk (%s).\n"
- "(I'm only showing ones of at least %dMB.)\n\n",
- SORNOT(nr_regions), prettysizeprint(table[0].size/2),
- MIN_REGION_MB);
+ printf("\nI've found the following region%s on this disk (%s).\n\n",
+ SORNOT(nr_regions), prettysizeprint(table[0].size/2));
for(r = 0; r < nr_regions; r++, reg++) {
unsigned long units;
if(reg->used_part) {
}
int
-scribble_region(region_t *reg)
+scribble_region(region_t *reg, struct part_entry **pe)
{
int ex, trunc = 0, changed = 0, i;
struct part_entry *newpart;
}
}
if(trunc) {
- printf("\nShrunk region to %dMB.\n", MAX_REGION_MB);
+ printf("\nWill only use %dMB.\n", MAX_REGION_MB);
}
if(!reg->used_part) {
for(i = 1; i <= NR_PARTITIONS; i++)
newpart->lowsec = reg->free_sec_start;
newpart->size = reg->free_sec_last - reg->free_sec_start + 1;
changed = 1;
- } else newpart = reg->used_part;
+ } else newpart = reg->used_part;
newpart->sysind = MINIX_PART;
+ *pe = newpart;
changed = 1;
return changed;
}
int
-do_autopart(void)
+do_autopart(int resultfd)
{
region_t *r;
+ struct part_entry *pe;
nordonly = 1;
probing = 1;
} while(!r);
/* Write things. */
- if(scribble_region(r)) {
+ if(scribble_region(r, &pe)) {
+ int i, found = -1;
+ char partbuf[100];
dirty = 1;
m_write('w', NULL);
- return !dirty;
+ if(dirty) return 1;
+ /* Retrieve partition number in sorted order that we
+ * have scribbled in.
+ */
+ sort();
+ for(i = 1; i <= NR_PARTITIONS; i++) {
+ if(table[sort_order[i]].lowsec == pe->lowsec) {
+ if(found > 0) {
+ fprintf(stderr, "Internal error (1).\n");
+ return 1;
+ }
+ found = i;
+ }
+ }
+ if(found < 1) {
+ fprintf(stderr, "Internal error (2).\n");
+ return 1;
+ }
+ sprintf(partbuf, "%sp%d\n", curdev->name, found-1);
+ if(resultfd >= 0 && write(resultfd, partbuf, strlen(partbuf)) < strlen(partbuf)) {
+ fprintf(stderr, "Couldn't write result.\n");
+ return 1;
+ }
+ return 0;
}
return 1;
struct part_entry *pe;
char *name;
int autopart = 0;
+ int resultfd = -1;
/* Autopilot mode if invoked as autopart. */
if(!(name = strrchr(argv[0], '/'))) name = argv[0];
op= newobject(O_SIZE, OF_MOD, r, 69, 9); op->entry= pe;
op= newobject(O_KB, OF_MOD, r, 79, 9); op->entry= pe;
}
+ } else {
+ int c;
+ /* autopart uses getopt() */
+ while((c = getopt(argc, argv, "f:")) != EOF) {
+ switch(c) {
+ case 'f':
+ unlink(optarg);
+ if((resultfd=open(optarg, O_CREAT | O_WRONLY | O_TRUNC)) < 0) {
+ perror(optarg);
+ return 1;
+ }
+ break;
+ default:
+ fprintf(stderr, "Unknown option\n");
+ return 1;
+ }
+ }
+ argc--;
+ argv++;
}
for (i= 1; i < argc; i++) newdevice(argv[i], 0, 0);
}
if(autopart) {
+ int r;
if (firstdev == nil) {
fprintf(stderr, "autopart couldn't find any devices.\n");
return 1;
}
- return do_autopart();
+ r = do_autopart(resultfd);
+ if(resultfd >= 0) { close(resultfd); }
+ return r;
}
if (firstdev != nil) {
while getopts '' opt; do usage; done
shift `expr $OPTIND - 1`
-# Installing a floppy set?
-case $# in
-0) # No, we're installing a skeleton system on the hard disk.
- ;;
-1)
- cd "$1" || exit
-
- # Annoying message still there?
- grep "'setup /usr'" /etc/issue >/dev/null 2>&1 && rm -f /etc/issue
-
- if [ -t 0 ]
- then
- size=bad
- while [ "$size" = bad ]
- do
- echo -n "\
-What is the size of the images on the diskettes? [all] "; read size
-
- case $size in
- ''|360|720|1200|1440)
- ;;
- *) echo "Sorry, I don't believe \"$size\", try again." >&2
- size=bad
- esac
- done
-
- drive=
- while [ -z "$drive" ]
- do
- echo -n "What floppy drive to use? [0] "; read drive
-
- case $drive in
- '') drive=0
- ;;
- [01])
- ;;
- *) echo "It must be 0 or 1, not \"$drive\"."
- drive=
- esac
- done
-
- vol -r $size /dev/fd$drive | uncompress | tar xvfp -
- else
- # Standard input is where we can get our files from.
- uncompress | tar xvfp -
- fi
-
- echo Done.
- exit
- ;;
-*)
- usage
-esac
+if [ "$USER" != root ]
+then echo "Please run setupcd as root."
+ exit 1
+fi
# Installing Minix on the hard disk.
-# Must be in / or we can't mount or umount.
-if [ ! -f /CD ]
-then
- case "`pwd`" in
- /?*)
- echo "Please type 'cd /' first, you are locking up `pwd`" >&2
- exit 1
- esac
-fi
case "$0" in
/tmp/*)
/dev/fd*:/dev/fd*) fdroot=$thisroot # ROOT is mounted directly
;;
*) fdroot=$thisroot # ?
- if [ -f /CD ]
- then
- :
- else
- echo -n "\
-It looks like Minix has been installed on disk already. Are you sure you
-know what you are doing? [n] "
- read yn
- case "$yn" in
- [yY]*|sure) ;;
- *) exit
- esac
- fi
esac
echo -n "\
This is the Minix installation script.
Note 1: If the screen blanks suddenly then hit CTRL+F3 to select \"software
- scrolling\".
+scrolling\".
Note 2: If things go wrong then hit DEL and start over.
Keyboard type? [us-std] "; read keymap
test -n "$keymap" && loadkeys "/usr/lib/keymaps/$keymap.map"
+echo -n "Welcome to Minix partitioning. Do you want to
+follow the (A)utomatic or the e(X)pert mode? Expert mode drops
+you into part to let you edit your partition table to taste.
+Automatic mode is much easier, but can't handle all cases. In
+cases it can't handle, it will tell you to use expert mode.
+Please choose, A for Automatic, or X for Expert: "
+
+read ch
+case "$ch" in
+[Aa]*) auto="1" ;;
+[Xx]*) auto="" ;;
+*) echo "Unrecognized response."; exit 1;
+esac
+
+primary=
+
+if [ -z "$auto" ]
+then
+ # Expert mode
echo -n "
Minix needs one primary partition of at about 210 MB for a full install
with sources. (The full install also fits in about 180 MB, but it
Please note the name of the partition (e.g. c0d0p1, c0d1p3, c1d1p0) you
make. (See the devices section in usage(8) on Minix device names.)
:"
-read ret
+ read ret
-primary=
-while [ -z "$primary" ]
-do
- part || exit
+ while [ -z "$primary" ]
+ do
+ part || exit
- echo -n "
+ echo -n "
Please finish the name of the primary partition you have created:
(Just type RETURN if you want to rerun \"part\") /dev/"
- read primary
-done
+ read primary
+ done
+else
+ # Automatic mode
+ while [ -z "$primary" ]
+ do
+ PF="/tmp/pf"
+ echo -n "Press return to enter the autopart tool, or DEL to abort.
+:"
+ read ret
+ if autopart -f$PF
+ then if [ -s "$PF" ]
+ then
+ bd="`cat $PF`"
+ if [ -b "$bd" ]
+ then primary="$bd"
+ else echo "Funny device $bd from autopart."
+ fi
+ else
+ echo "Didn't find output from autopart."
+ fi
+ else echo "Autopart tool failed. Trying again."
+ fi
+ done
+
+fi
root=${primary}s0
swap=${primary}s1
usr=${primary}s2
+echo "$root $usr"
+exit 1
+
hex2int()
{
# Translate hexadecimal to integer.
mkfs /dev/$root || exit
mount /dev/$root /mnt || exit
-if [ -d /boot ]
-then
- # Running from the floppy itself (or installation CD).
- cpdir -vx / /mnt || exit
- chmod 555 /mnt/usr
-else
- # Running from the RAM disk, root image is on a floppy.
- mount $fdroot /root || exit
- cpdir -v /root /mnt || exit
- umount $fdroot || exit
- cpdir -f /dev /mnt/dev # Copy any extra MAKEDEV'd devices
-fi
+# Running from the installation CD.
+cpdir -vx / /mnt || exit
+chmod 555 /mnt/usr
# CD remnants that aren't for the installed system
rm /mnt/etc/issue /mnt/CD 2>/dev/null