More code rearrangment, moved all mbr code into its own file
so it can be used by other programs. Added all the necessary menus to take the user through the installation of the bootblocks.
This commit is contained in:
parent
7ffa8327b2
commit
26b2d70e8e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=3727
@ -4,7 +4,7 @@ NOMAN= yet
|
|||||||
|
|
||||||
.PATH: /usr/src/sbin/disklabel
|
.PATH: /usr/src/sbin/disklabel
|
||||||
|
|
||||||
SRCS = sysinstall.c dkcksum.c bootarea.c
|
SRCS = sysinstall.c dkcksum.c bootarea.c mbr.c
|
||||||
|
|
||||||
CFLAGS += -Wall
|
CFLAGS += -Wall
|
||||||
LDADD = -ldialog -lncurses -lmytinfo
|
LDADD = -ldialog -lncurses -lmytinfo
|
||||||
|
@ -24,63 +24,21 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "mbr.h"
|
||||||
#include "bootarea.h"
|
#include "bootarea.h"
|
||||||
#include "sysinstall.h"
|
#include "sysinstall.h"
|
||||||
|
|
||||||
char boot1[] = BOOT1;
|
char boot1[] = BOOT1;
|
||||||
char boot2[] = BOOT2;
|
char boot2[] = BOOT2;
|
||||||
|
|
||||||
struct part_type part_types[] =
|
|
||||||
{
|
|
||||||
{0x00, "unused"}
|
|
||||||
,{0x01, "Primary DOS with 12 bit FAT"}
|
|
||||||
,{0x02, "XENIX / filesystem"}
|
|
||||||
,{0x03, "XENIX /usr filesystem"}
|
|
||||||
,{0x04, "Primary DOS with 16 bit FAT"}
|
|
||||||
,{0x05, "Extended DOS"}
|
|
||||||
,{0x06, "Primary 'big' DOS (> 32MB)"}
|
|
||||||
,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"}
|
|
||||||
,{0x08, "AIX filesystem"}
|
|
||||||
,{0x09, "AIX boot partition or Coherent"}
|
|
||||||
,{0x0A, "OS/2 Boot Manager or OPUS"}
|
|
||||||
,{0x10, "OPUS"}
|
|
||||||
,{0x40, "VENIX 286"}
|
|
||||||
,{0x50, "DM"}
|
|
||||||
,{0x51, "DM"}
|
|
||||||
,{0x52, "CP/M or Microport SysV/AT"}
|
|
||||||
,{0x56, "GB"}
|
|
||||||
,{0x61, "Speed"}
|
|
||||||
,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"}
|
|
||||||
,{0x64, "Novell Netware 2.xx"}
|
|
||||||
,{0x65, "Novell Netware 3.xx"}
|
|
||||||
,{0x75, "PCIX"}
|
|
||||||
,{0x80, "Minix 1.1 ... 1.4a"}
|
|
||||||
,{0x81, "Minix 1.4b ... 1.5.10"}
|
|
||||||
,{0x82, "Linux"}
|
|
||||||
,{0x93, "Amoeba filesystem"}
|
|
||||||
,{0x94, "Amoeba bad block table"}
|
|
||||||
,{0xA5, "386BSD"}
|
|
||||||
,{0xB7, "BSDI BSD/386 filesystem"}
|
|
||||||
,{0xB8, "BSDI BSD/386 swap"}
|
|
||||||
,{0xDB, "Concurrent CPM or C.DOS or CTOS"}
|
|
||||||
,{0xE1, "Speed"}
|
|
||||||
,{0xE3, "Speed"}
|
|
||||||
,{0xE4, "Speed"}
|
|
||||||
,{0xF1, "Speed"}
|
|
||||||
,{0xF2, "DOS 3.3+ Secondary"}
|
|
||||||
,{0xF4, "Speed"}
|
|
||||||
,{0xFF, "BBT (Bad Blocks Table)"}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern char *bootblocks;
|
extern char *bootblocks;
|
||||||
extern struct bootarea *bootarea;
|
extern struct mbr *mbr;
|
||||||
|
|
||||||
int
|
int
|
||||||
enable_label(int fd)
|
enable_label(int fd)
|
||||||
{
|
{
|
||||||
int flag = 1;
|
int flag = 1;
|
||||||
if (ioctl(fd, DIOCWLABEL, &flag) < 0) {
|
if (ioctl(fd, DIOCWLABEL, &flag) < 0) {
|
||||||
sprintf(errmsg, "Write enable of disk failed\n");
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
@ -88,10 +46,9 @@ enable_label(int fd)
|
|||||||
|
|
||||||
int
|
int
|
||||||
disable_label(int fd)
|
disable_label(int fd)
|
||||||
{
|
{
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
if (ioctl(fd, DIOCWLABEL, &flag) < 0) {
|
if (ioctl(fd, DIOCWLABEL, &flag) < 0) {
|
||||||
sprintf(errmsg, "Write disable of disk failed\n");
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
@ -153,7 +110,8 @@ build_bootblocks(struct disklabel *label)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(fd, &bootblocks[label->d_secsize], (int)(label->d_bbsize - label->d_secsize)) < 0) {
|
if (read(fd, &bootblocks[label->d_secsize],
|
||||||
|
(int)(label->d_bbsize - label->d_secsize)) < 0) {
|
||||||
sprintf(errmsg, "Couldn't read from boot file %s\n", boot2);
|
sprintf(errmsg, "Couldn't read from boot file %s\n", boot2);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -163,16 +121,23 @@ build_bootblocks(struct disklabel *label)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write mbr partition table into bootblocks */
|
||||||
|
|
||||||
|
bcopy(mbr->dospart, &bootblocks[DOSPARTOFF],
|
||||||
|
sizeof(struct dos_partition) * NDOSPART);
|
||||||
|
|
||||||
/* Write the disklabel into the bootblocks */
|
/* Write the disklabel into the bootblocks */
|
||||||
|
|
||||||
label->d_checksum = dkcksum(label);
|
label->d_checksum = dkcksum(label);
|
||||||
bcopy(label, &bootblocks[(LABELSECTOR * label->d_secsize) + LABELOFFSET], sizeof *label);
|
bcopy(label, &bootblocks[(LABELSECTOR * label->d_secsize) + LABELOFFSET],
|
||||||
|
sizeof *label);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a size in Mb to a round number of cylinders */
|
||||||
int
|
int
|
||||||
calc_sects(int size, struct disklabel *label)
|
Mb_to_cylbdry(int size, struct disklabel *label)
|
||||||
{
|
{
|
||||||
int nsects, ncyls;
|
int nsects, ncyls;
|
||||||
|
|
||||||
@ -184,7 +149,7 @@ calc_sects(int size, struct disklabel *label)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
build_disklabel(struct disklabel *label, int avail_sects, int offset)
|
default_disklabel(struct disklabel *label, int avail_sects, int offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
int nsects;
|
int nsects;
|
||||||
@ -216,7 +181,7 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset)
|
|||||||
label->d_partitions[3].p_frag = DEFFRAG;
|
label->d_partitions[3].p_frag = DEFFRAG;
|
||||||
|
|
||||||
/* Default root */
|
/* Default root */
|
||||||
nsects = calc_sects(DEFROOTSIZE, label);
|
nsects = Mb_to_cylbdry(DEFROOTSIZE, label);
|
||||||
|
|
||||||
label->d_partitions[0].p_size = nsects;
|
label->d_partitions[0].p_size = nsects;
|
||||||
label->d_partitions[0].p_offset = offset;
|
label->d_partitions[0].p_offset = offset;
|
||||||
@ -226,7 +191,7 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset)
|
|||||||
|
|
||||||
avail_sects -= nsects;
|
avail_sects -= nsects;
|
||||||
offset += nsects;
|
offset += nsects;
|
||||||
nsects = calc_sects(DEFSWAPSIZE, label);
|
nsects = Mb_to_cylbdry(DEFSWAPSIZE, label);
|
||||||
|
|
||||||
label->d_partitions[1].p_size = nsects;
|
label->d_partitions[1].p_size = nsects;
|
||||||
label->d_partitions[1].p_offset = offset;
|
label->d_partitions[1].p_offset = offset;
|
||||||
@ -236,7 +201,7 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset)
|
|||||||
|
|
||||||
avail_sects -= nsects;
|
avail_sects -= nsects;
|
||||||
offset += nsects;
|
offset += nsects;
|
||||||
nsects = calc_sects(DEFUSRSIZE, label);
|
nsects = Mb_to_cylbdry(DEFUSRSIZE, label);
|
||||||
|
|
||||||
if (avail_sects > nsects)
|
if (avail_sects > nsects)
|
||||||
nsects = avail_sects;
|
nsects = avail_sects;
|
||||||
@ -254,22 +219,6 @@ build_disklabel(struct disklabel *label, int avail_sects, int offset)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
|
||||||
part_type(int type)
|
|
||||||
{
|
|
||||||
int num_types = (sizeof(part_types)/sizeof(struct part_type));
|
|
||||||
int next_type = 0;
|
|
||||||
struct part_type *ptr = part_types;
|
|
||||||
|
|
||||||
while (next_type < num_types) {
|
|
||||||
if(ptr->type == type)
|
|
||||||
return(ptr->name);
|
|
||||||
ptr++;
|
|
||||||
next_type++;
|
|
||||||
}
|
|
||||||
return("Uknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
disk_size(int disk)
|
disk_size(int disk)
|
||||||
{
|
{
|
||||||
@ -280,45 +229,3 @@ disk_size(int disk)
|
|||||||
* label->d_ntracks * label->d_ncylinders;
|
* label->d_ntracks * label->d_ncylinders;
|
||||||
return(size/1024/1024);
|
return(size/1024/1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
read_bootarea(int fd)
|
|
||||||
{
|
|
||||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
|
||||||
sprintf(errmsg, "Couldn't seek for bootarea read\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
if (read(fd, &(bootarea->bootcode), 512) == -1) {
|
|
||||||
sprintf(errmsg, "Failed to read bootarea\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
/* Validate the bootarea */
|
|
||||||
/* XXX -- need to validate contents too */
|
|
||||||
if (bootarea->signature != BOOT_MAGIC) {
|
|
||||||
sprintf(errmsg, "Bootarea invalid\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
write_bootarea(int fd)
|
|
||||||
{
|
|
||||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
|
||||||
sprintf(errmsg, "Couldn't seek for bootarea write\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enable_label(fd) == -1)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
if (write(fd, bootarea, sizeof(bootarea)) == -1) {
|
|
||||||
sprintf(errmsg, "Failed to write bootarea\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disable_label(fd) == -1)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
* its use.
|
* its use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BOOT_MAGIC 0xAA55
|
|
||||||
#define ACTIVE 0x80
|
|
||||||
#define BOOT1 "/usr/mdec/sdboot"
|
#define BOOT1 "/usr/mdec/sdboot"
|
||||||
#define BOOT2 "/usr/mdec/bootsd"
|
#define BOOT2 "/usr/mdec/bootsd"
|
||||||
|
|
||||||
@ -21,26 +19,10 @@
|
|||||||
#define DEFFSIZE 1024
|
#define DEFFSIZE 1024
|
||||||
#define DEFFRAG 8
|
#define DEFFRAG 8
|
||||||
|
|
||||||
extern char *part_type(int);
|
int enable_label(int);
|
||||||
extern int disk_size(int);
|
int disable_label(int);
|
||||||
extern int enable_label(int);
|
int write_bootblocks(int, off_t, int);
|
||||||
extern int disable_label(int);
|
int build_bootblocks(struct disklabel *);
|
||||||
extern int write_bootblocks(int, off_t, int);
|
int Mb_to_cylbdry(int, struct disklabel *);
|
||||||
extern int build_bootblocks(struct disklabel *);
|
void default_disklabel(struct disklabel *, int, int);
|
||||||
extern void build_disklabel(struct disklabel *, int, int);
|
int disk_size(int);
|
||||||
extern int write_bootarea(int);
|
|
||||||
extern int read_bootarea(int);
|
|
||||||
|
|
||||||
struct bootarea
|
|
||||||
{
|
|
||||||
unsigned char padding[2]; /* force longs to be long aligned */
|
|
||||||
unsigned char bootcode[DOSPARTOFF];
|
|
||||||
struct dos_partition dospart[4];
|
|
||||||
unsigned short signature;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct part_type
|
|
||||||
{
|
|
||||||
unsigned char type;
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
|
193
sbin/sysinstall/mbr.c
Normal file
193
sbin/sysinstall/mbr.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1994, Paul Richards.
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software may be used, modified, copied, distributed, and
|
||||||
|
* sold, in both source and binary form provided that the above
|
||||||
|
* copyright and these terms are retained, verbatim, as the first
|
||||||
|
* lines of this file. Under no circumstances is the author
|
||||||
|
* responsible for the proper functioning of this software, nor does
|
||||||
|
* the author assume any responsibility for damages incurred with
|
||||||
|
* its use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/disklabel.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <dialog.h>
|
||||||
|
|
||||||
|
#include "mbr.h"
|
||||||
|
|
||||||
|
extern struct mbr *mbr;
|
||||||
|
extern char *errmsg;
|
||||||
|
extern int inst_part;
|
||||||
|
|
||||||
|
struct part_type part_types[] = PARTITION_TYPES
|
||||||
|
|
||||||
|
char *
|
||||||
|
part_type(int type)
|
||||||
|
{
|
||||||
|
int num_types = (sizeof(part_types)/sizeof(struct part_type));
|
||||||
|
int next_type = 0;
|
||||||
|
struct part_type *ptr = part_types;
|
||||||
|
|
||||||
|
while (next_type < num_types) {
|
||||||
|
if(ptr->type == type)
|
||||||
|
return(ptr->name);
|
||||||
|
ptr++;
|
||||||
|
next_type++;
|
||||||
|
}
|
||||||
|
return("Uknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
read_mbr(int fd, struct mbr *mbr)
|
||||||
|
{
|
||||||
|
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||||
|
sprintf(errmsg, "Couldn't seek for master boot record read\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if (read(fd, &(mbr->bootcode), 512) == -1) {
|
||||||
|
sprintf(errmsg, "Failed to read master boot record\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
/* Validate the master boot record */
|
||||||
|
if (mbr->magic != MBR_MAGIC) {
|
||||||
|
sprintf(errmsg, "Master boot record is invalid\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
write_mbr(int fd, struct mbr *mbr)
|
||||||
|
{
|
||||||
|
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||||
|
sprintf(errmsg, "Couldn't seek for master boot record write\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write(fd, mbr->bootcode, MBRSIZE) == -1) {
|
||||||
|
sprintf(errmsg, "Failed to write master boot record\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
show_mbr(struct mbr *mbr)
|
||||||
|
{
|
||||||
|
int i, j, key = 0;
|
||||||
|
int x, y;
|
||||||
|
WINDOW *window;
|
||||||
|
|
||||||
|
window = newwin(LINES, COLS, 0, 0);
|
||||||
|
keypad(window, TRUE);
|
||||||
|
|
||||||
|
draw_box(window, 0, 0, LINES - 1, COLS - 1,
|
||||||
|
COLOR_PAIR(COLOR_YELLOW), COLOR_PAIR(COLOR_BLUE));
|
||||||
|
|
||||||
|
for (i=0; i<NDOSPART/2; i++) {
|
||||||
|
for (j=0; j<NDOSPART/2; j++) {
|
||||||
|
x = (j * 38) + 3;
|
||||||
|
y = (i * 11) + 2;
|
||||||
|
mvwprintw(window, y, x, "Partition %d: flags = %x",
|
||||||
|
(i*2)+j, mbr->dospart[(i*2)+j].dp_flag);
|
||||||
|
mvwprintw(window, y+1, x, "Starting at (H%d, S%d, C%d)",
|
||||||
|
mbr->dospart[(i*2)+j].dp_shd,
|
||||||
|
mbr->dospart[(i*2)+j].dp_ssect,
|
||||||
|
mbr->dospart[(i*2)+j].dp_scyl);
|
||||||
|
mvwprintw(window, y+2, x, "Type: %s (%x)",
|
||||||
|
part_type(mbr->dospart[(i*2)+j].dp_typ),
|
||||||
|
mbr->dospart[(i*2)+j].dp_typ);
|
||||||
|
mvwprintw(window, y+3, x, "Ending at (H%d, S%d, C%d)",
|
||||||
|
mbr->dospart[(i*2)+j].dp_shd,
|
||||||
|
mbr->dospart[(i*2)+j].dp_esect,
|
||||||
|
mbr->dospart[(i*2)+j].dp_ecyl);
|
||||||
|
mvwprintw(window, y+4, x, "Absolute start sector %ld",
|
||||||
|
mbr->dospart[(i*2)+j].dp_start);
|
||||||
|
mvwprintw(window, y+5, x, "Size %ld", mbr->dospart[(i*2)+j].dp_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
while (key != '\n')
|
||||||
|
key = wgetch(window);
|
||||||
|
|
||||||
|
delwin(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clear_mbr(struct mbr *mbr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Create an empty partition table */
|
||||||
|
for (i=0; i < NDOSPART; i++) {
|
||||||
|
mbr->dospart[i].dp_flag = 0;
|
||||||
|
mbr->dospart[i].dp_shd = 0;
|
||||||
|
mbr->dospart[i].dp_ssect = 0;
|
||||||
|
mbr->dospart[i].dp_scyl = 0;
|
||||||
|
mbr->dospart[i].dp_typ = 0;
|
||||||
|
mbr->dospart[i].dp_ehd = 0;
|
||||||
|
mbr->dospart[i].dp_esect = 0;
|
||||||
|
mbr->dospart[i].dp_ecyl = 0;
|
||||||
|
mbr->dospart[i].dp_start = 0;
|
||||||
|
mbr->dospart[i].dp_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
build_mbr(struct mbr *mbr, struct disklabel *label)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the biggie, need to spend some time getting all
|
||||||
|
* the different possibilities sorted out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (inst_part == -1) {
|
||||||
|
/* Install to entire disk */
|
||||||
|
clear_mbr(mbr);
|
||||||
|
mbr->dospart[0].dp_flag = ACTIVE;
|
||||||
|
mbr->dospart[0].dp_shd = 1;
|
||||||
|
mbr->dospart[0].dp_ssect = 0;
|
||||||
|
mbr->dospart[0].dp_scyl = 0;
|
||||||
|
mbr->dospart[0].dp_typ = DOSPTYP_386BSD ;
|
||||||
|
mbr->dospart[0].dp_ehd = label->d_ntracks;
|
||||||
|
mbr->dospart[0].dp_esect = label->d_nsectors;
|
||||||
|
mbr->dospart[0].dp_ecyl = label->d_ncylinders;
|
||||||
|
mbr->dospart[0].dp_start = 0;
|
||||||
|
mbr->dospart[0].dp_size =
|
||||||
|
label->d_ntracks * label->d_nsectors * label->d_ncylinders;
|
||||||
|
return(1);
|
||||||
|
} else {
|
||||||
|
/* Validate partition - XXX need to spend some time making this robust */
|
||||||
|
if ((inst_part) && (!mbr->dospart[inst_part].dp_start)) {
|
||||||
|
strcpy(errmsg, "The start address of the selected partition is 0\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set partition type to FreeBSD and make it the only active partition */
|
||||||
|
for (i=0; i < NDOSPART; i++)
|
||||||
|
mbr->dospart[i].dp_flag &= ~ACTIVE;
|
||||||
|
mbr->dospart[inst_part].dp_typ = DOSPTYP_386BSD;
|
||||||
|
mbr->dospart[inst_part].dp_flag = ACTIVE;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
edit_mbr(struct mbr *mbr, struct disklabel *label)
|
||||||
|
{
|
||||||
|
|
||||||
|
dialog_msgbox("DOS partition table editor",
|
||||||
|
"This editor is still under construction :-)", 10, 75, 1);
|
||||||
|
show_mbr(mbr);
|
||||||
|
}
|
83
sbin/sysinstall/mbr.h
Normal file
83
sbin/sysinstall/mbr.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1994, Paul Richards.
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software may be used, modified, copied, distributed, and
|
||||||
|
* sold, in both source and binary form provided that the above
|
||||||
|
* copyright and these terms are retained, verbatim, as the first
|
||||||
|
* lines of this file. Under no circumstances is the author
|
||||||
|
* responsible for the proper functioning of this software, nor does
|
||||||
|
* the author assume any responsibility for damages incurred with
|
||||||
|
* its use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MBRSIZE 512
|
||||||
|
#define MBR_MAGIC 0xAA55
|
||||||
|
#define ACTIVE 0x80
|
||||||
|
|
||||||
|
struct mbr
|
||||||
|
{
|
||||||
|
unsigned char padding[2]; /* force longs to be long aligned */
|
||||||
|
unsigned char bootcode[DOSPARTOFF];
|
||||||
|
struct dos_partition dospart[4];
|
||||||
|
unsigned short magic;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct part_type
|
||||||
|
{
|
||||||
|
unsigned char type;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PARTITION_TYPES \
|
||||||
|
{ \
|
||||||
|
{0x00, "Unused"} \
|
||||||
|
,{0x01, "Primary DOS with 12 bit FAT"} \
|
||||||
|
,{0x02, "XENIX / filesystem"} \
|
||||||
|
,{0x03, "XENIX /usr filesystem"} \
|
||||||
|
,{0x04, "Primary DOS with 16 bit FAT"} \
|
||||||
|
,{0x05, "Extended DOS"} \
|
||||||
|
,{0x06, "Primary 'big' DOS (> 32MB)"} \
|
||||||
|
,{0x07, "OS/2 HPFS, QNX or Advanced UNIX"} \
|
||||||
|
,{0x08, "AIX filesystem"} \
|
||||||
|
,{0x09, "AIX boot partition or Coherent"} \
|
||||||
|
,{0x0A, "OS/2 Boot Manager or OPUS"} \
|
||||||
|
,{0x10, "OPUS"} \
|
||||||
|
,{0x40, "VENIX 286"} \
|
||||||
|
,{0x50, "DM"} \
|
||||||
|
,{0x51, "DM"} \
|
||||||
|
,{0x52, "CP/M or Microport SysV/AT"} \
|
||||||
|
,{0x56, "GB"} \
|
||||||
|
,{0x61, "Speed"} \
|
||||||
|
,{0x63, "ISC UNIX, other System V/386, GNU HURD or Mach"} \
|
||||||
|
,{0x64, "Novell Netware 2.xx"} \
|
||||||
|
,{0x65, "Novell Netware 3.xx"} \
|
||||||
|
,{0x75, "PCIX"} \
|
||||||
|
,{0x80, "Minix 1.1 ... 1.4a"} \
|
||||||
|
,{0x81, "Minix 1.4b ... 1.5.10"} \
|
||||||
|
,{0x82, "Linux"} \
|
||||||
|
,{0x93, "Amoeba filesystem"} \
|
||||||
|
,{0x94, "Amoeba bad block table"} \
|
||||||
|
,{0xA5, "FreeBSD/NetBSD/386BSD"} \
|
||||||
|
,{0xB7, "BSDI BSD/386 filesystem"} \
|
||||||
|
,{0xB8, "BSDI BSD/386 swap"} \
|
||||||
|
,{0xDB, "Concurrent CPM or C.DOS or CTOS"} \
|
||||||
|
,{0xE1, "Speed"} \
|
||||||
|
,{0xE3, "Speed"} \
|
||||||
|
,{0xE4, "Speed"} \
|
||||||
|
,{0xF1, "Speed"} \
|
||||||
|
,{0xF2, "DOS 3.3+ Secondary"} \
|
||||||
|
,{0xF4, "Speed"} \
|
||||||
|
,{0xFF, "BBT (Bad Blocks Table)"} \
|
||||||
|
};
|
||||||
|
|
||||||
|
extern char *part_type(int);
|
||||||
|
extern int enable_label(int);
|
||||||
|
extern int disable_label(int);
|
||||||
|
extern int write_mbr(int, struct mbr *);
|
||||||
|
extern int read_mbr(int, struct mbr *);
|
||||||
|
extern void show_mbr(struct mbr *);
|
||||||
|
extern void clear_mbr(struct mbr *);
|
||||||
|
extern void edit_mbr(struct mbr *, struct disklabel *);
|
||||||
|
extern int build_mbr(struct mbr *, struct disklabel *);
|
@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
#define DEBUG
|
||||||
* Copyright (c) 1994, Paul Richards.
|
* Copyright (c) 1994, Paul Richards.
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <ncurses.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
@ -28,16 +30,15 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
#include <machine/console.h>
|
#include <machine/console.h>
|
||||||
|
|
||||||
|
#include "mbr.h"
|
||||||
#include "bootarea.h"
|
#include "bootarea.h"
|
||||||
#include "sysinstall.h"
|
#include "sysinstall.h"
|
||||||
|
|
||||||
char xxboot[] = "/usr/mdec/sdboot";
|
|
||||||
char bootxx[] = "/usr/mdec/bootsd";
|
|
||||||
|
|
||||||
struct disklabel *avail_disklabels;
|
struct disklabel *avail_disklabels;
|
||||||
int *avail_fds;
|
int *avail_fds;
|
||||||
unsigned char **options;
|
unsigned char **options;
|
||||||
@ -45,7 +46,9 @@ unsigned char **avail_disknames;
|
|||||||
unsigned char *scratch;
|
unsigned char *scratch;
|
||||||
unsigned char *errmsg;
|
unsigned char *errmsg;
|
||||||
unsigned char *bootblocks;
|
unsigned char *bootblocks;
|
||||||
struct bootarea *bootarea;
|
struct mbr *mbr;
|
||||||
|
struct utsname utsname;
|
||||||
|
unsigned char *title = utsname.sysname;
|
||||||
|
|
||||||
struct sysinstall *sysinstall;
|
struct sysinstall *sysinstall;
|
||||||
struct sysinstall *sequence;
|
struct sysinstall *sequence;
|
||||||
@ -56,9 +59,9 @@ int inst_part = 0;
|
|||||||
int custom_install;
|
int custom_install;
|
||||||
int dialog_active = 0;
|
int dialog_active = 0;
|
||||||
|
|
||||||
void leave_sysinstall();
|
void exit_sysinstall();
|
||||||
void abort_task();
|
void abort_installation(char *);
|
||||||
void cleanup();
|
void exit_prompt();
|
||||||
void fatal(char *);
|
void fatal(char *);
|
||||||
extern char *part_type(int);
|
extern char *part_type(int);
|
||||||
extern int disk_size(int);
|
extern int disk_size(int);
|
||||||
@ -67,26 +70,22 @@ extern int disk_size(int);
|
|||||||
char selection[30];
|
char selection[30];
|
||||||
|
|
||||||
void
|
void
|
||||||
abort_task(char *prompt)
|
abort_installation(char *prompt)
|
||||||
{
|
{
|
||||||
strcat(prompt,"\n\n Do you wish to abort the installation ?");
|
strcpy(scratch, prompt);
|
||||||
if (!dialog_yesno("ABORT",prompt,10,75))
|
strcat(scratch,"\n\n Do you wish to abort the installation ?");
|
||||||
leave_sysinstall();
|
if (!dialog_yesno("Abort installation ?",scratch,10,75))
|
||||||
|
exit_prompt();
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
leave_sysinstall()
|
exit_prompt()
|
||||||
{
|
{
|
||||||
sprintf(scratch,"Are you sure you want to exit sysinstall?");
|
sprintf(scratch,"Are you sure you want to exit sysinstall?");
|
||||||
if (!dialog_yesno("Exit sysinstall",scratch,10,75)) {
|
if (!dialog_yesno("Exit sysinstall",scratch,10,75))
|
||||||
if (getpid() == 1) {
|
exit_sysinstall();
|
||||||
if (reboot(RB_AUTOBOOT) == -1)
|
clear();
|
||||||
fatal("Reboot failed!");
|
|
||||||
} else {
|
|
||||||
cleanup();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -128,8 +127,8 @@ alloc_memory()
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bootarea = (struct bootarea *) malloc(sizeof(struct bootarea));
|
mbr = (struct mbr *) malloc(sizeof(struct mbr));
|
||||||
if (!bootarea)
|
if (!mbr)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
|
||||||
bootblocks = (char *) malloc(BBSIZE);
|
bootblocks = (char *) malloc(BBSIZE);
|
||||||
@ -165,40 +164,42 @@ free_memory()
|
|||||||
free(options[i]);
|
free(options[i]);
|
||||||
free(options);
|
free(options);
|
||||||
|
|
||||||
free(bootarea);
|
free(mbr);
|
||||||
free(bootblocks);
|
free(bootblocks);
|
||||||
free(sysinstall);
|
free(sysinstall);
|
||||||
free(sequence);
|
free(sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cleanup()
|
exit_sysinstall()
|
||||||
{
|
{
|
||||||
free_memory();
|
if (getpid() == 1) {
|
||||||
if (dialog_active)
|
if (reboot(RB_AUTOBOOT) == -1)
|
||||||
end_dialog();
|
if (dialog_active)
|
||||||
|
while (1)
|
||||||
|
dialog_msgbox("Exit sysinstall",
|
||||||
|
"Reboot failed -- hit reset",
|
||||||
|
10, 75, 20);
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Reboot failed -- hit reset");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
free_memory();
|
||||||
|
if (dialog_active)
|
||||||
|
end_dialog();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fatal(char *errmsg)
|
fatal(char *errmsg)
|
||||||
{
|
{
|
||||||
if (dialog_active)
|
if (dialog_active)
|
||||||
dialog_msgbox("Fatal Error -- Aborting installation", errmsg, 10, 75, 20);
|
dialog_msgbox("Fatal Error -- Aborting installation", errmsg, 10, 75, 20);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Fatal Error -- Aborting installation:\n%s\n", errmsg);
|
fprintf(stderr, "Fatal Error -- Aborting installation:\n%s\n", errmsg);
|
||||||
if (getpid() == 1) {
|
exit_sysinstall();
|
||||||
if (reboot(RB_AUTOBOOT) == -1)
|
|
||||||
while (1)
|
|
||||||
if (dialog_active)
|
|
||||||
dialog_msgbox("Fatal Error -- Aborting installation",
|
|
||||||
"Reboot failed after a fatal error -- hit reset", 10, 75, 20);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "Fatal Error -- Aborting installation:\n%s\n",
|
|
||||||
"Reboot failed after a fatal error -- hit reset");
|
|
||||||
} else {
|
|
||||||
cleanup();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -210,6 +211,7 @@ query_disks()
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
no_disks = 0;
|
||||||
for (i=0;i<10;i++) {
|
for (i=0;i<10;i++) {
|
||||||
sprintf(diskname,"wd%d",i);
|
sprintf(diskname,"wd%d",i);
|
||||||
sprintf(disk,"/dev/r%sd",diskname);
|
sprintf(disk,"/dev/r%sd",diskname);
|
||||||
@ -252,9 +254,10 @@ select_disk()
|
|||||||
|
|
||||||
if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, no_disks, options, selection)) {
|
if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, no_disks, options, selection)) {
|
||||||
sprintf(scratch,"You did not select a valid disk");
|
sprintf(scratch,"You did not select a valid disk");
|
||||||
abort_task(scratch);
|
abort_installation(scratch);
|
||||||
valid = 0;
|
valid = 0;
|
||||||
}
|
}
|
||||||
|
clear();
|
||||||
} while (!valid);
|
} while (!valid);
|
||||||
return(atoi(selection) - 1);
|
return(atoi(selection) - 1);
|
||||||
}
|
}
|
||||||
@ -264,22 +267,33 @@ select_partition(int disk)
|
|||||||
{
|
{
|
||||||
int valid;
|
int valid;
|
||||||
int i;
|
int i;
|
||||||
|
int choice;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
valid = 1;
|
valid = 1;
|
||||||
|
|
||||||
sprintf(scratch,"The following partitions were found on this disk");
|
sprintf(scratch,"Select one of the following areas to install to:");
|
||||||
for (i=0;i<4;i++) {
|
sprintf(options[0], "%d", 0);
|
||||||
sprintf(options[(i*2)], "%d",i+1);
|
sprintf(options[1], "%s, (%dMb)", "Install to entire disk",
|
||||||
sprintf(options[(i*2)+1], "%s, (%ldMb)",
|
disk_size(disk));
|
||||||
part_type(bootarea->dospart[i].dp_typ),
|
for (i=0; i < NDOSPART; i++) {
|
||||||
bootarea->dospart[i].dp_size * 512 / (1024 * 1024));
|
sprintf(options[(i*2)+2], "%d",i+1);
|
||||||
|
sprintf(options[(i*2)+3], "%s, (%ldMb)",
|
||||||
|
part_type(mbr->dospart[i].dp_typ),
|
||||||
|
mbr->dospart[i].dp_size * 512 / (1024 * 1024));
|
||||||
}
|
}
|
||||||
if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, 4, options, selection)) {
|
if (dialog_menu(title,
|
||||||
|
scratch, 10, 75, 5, 5, options, selection)) {
|
||||||
sprintf(scratch,"You did not select a valid partition");
|
sprintf(scratch,"You did not select a valid partition");
|
||||||
abort_task(scratch);
|
abort_installation(scratch);
|
||||||
valid = 0;
|
valid = 0;
|
||||||
}
|
}
|
||||||
|
clear();
|
||||||
|
choice = atoi(selection);
|
||||||
|
if (!choice)
|
||||||
|
if (dialog_yesno(title, "Installing to the whole disk will erase all its present data.\n\nAre you sure you want to do this?", 10, 75))
|
||||||
|
valid = 0;
|
||||||
|
clear();
|
||||||
} while (!valid);
|
} while (!valid);
|
||||||
|
|
||||||
return(atoi(selection) - 1);
|
return(atoi(selection) - 1);
|
||||||
@ -492,35 +506,86 @@ void
|
|||||||
stage1()
|
stage1()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int ok = 0;
|
||||||
|
int ready = 0;
|
||||||
struct ufs_args ufsargs;
|
struct ufs_args ufsargs;
|
||||||
|
|
||||||
query_disks();
|
while (!ready) {
|
||||||
inst_disk = select_disk();
|
ready = 1;
|
||||||
|
|
||||||
|
query_disks();
|
||||||
|
inst_disk = select_disk();
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
read_mbr(avail_fds[inst_disk], mbr);
|
||||||
|
show_mbr(mbr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (read_mbr(avail_fds[inst_disk], mbr) == -1) {
|
||||||
|
sprintf(scratch, "The following error occured will trying to read the master boot record:\n\n%s\n\nIn order to install FreeBSD a new master boot record will have to be written which will mean all current data on the hard disk will be lost.", errmsg);
|
||||||
|
ok = 0;
|
||||||
|
while (!ok) {
|
||||||
|
abort_installation(scratch);
|
||||||
|
if (!dialog_yesno(title, "Are you sure you wish to proceed?",
|
||||||
|
10, 75)) {
|
||||||
|
clear();
|
||||||
|
clear_mbr(mbr);
|
||||||
|
ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (custom_install)
|
||||||
|
if (!dialog_yesno(title, "Do you wish to edit the DOS partition table?",
|
||||||
|
10, 75)) {
|
||||||
|
clear();
|
||||||
|
edit_mbr(mbr, &avail_disklabels[inst_disk]);
|
||||||
|
}
|
||||||
|
|
||||||
if (read_bootarea(avail_fds[inst_disk]) == -1) {
|
|
||||||
/* Invalid boot area */
|
|
||||||
build_disklabel(&avail_disklabels[inst_disk],
|
|
||||||
avail_disklabels[inst_disk].d_secperunit, 0);
|
|
||||||
build_bootblocks(&avail_disklabels[inst_disk]);
|
|
||||||
write_bootblocks(avail_fds[inst_disk], 0,
|
|
||||||
avail_disklabels[inst_disk].d_bbsize);
|
|
||||||
} else {
|
|
||||||
inst_part = select_partition(inst_disk);
|
inst_part = select_partition(inst_disk);
|
||||||
/* Set partition to be FreeBSD and active */
|
|
||||||
for (i=0; i < NDOSPART; i++)
|
ok = 0;
|
||||||
bootarea->dospart[i].dp_flag &= ~ACTIVE;
|
while (!ok) {
|
||||||
bootarea->dospart[inst_part].dp_typ = DOSPTYP_386BSD;
|
if (build_mbr(mbr, &avail_disklabels[inst_disk]))
|
||||||
bootarea->dospart[inst_part].dp_flag = ACTIVE;
|
ok = 1;
|
||||||
write_bootarea(avail_fds[inst_disk]);
|
else {
|
||||||
build_disklabel(&avail_disklabels[inst_disk],
|
sprintf(scratch, "The DOS partition table is inconsistent.\n\n%s\n\nDo you wish to edit it by hand?", errmsg);
|
||||||
bootarea->dospart[inst_part].dp_size,
|
if (!dialog_yesno(title, scratch, 10, 75)) {
|
||||||
bootarea->dospart[inst_part].dp_start);
|
edit_mbr(mbr, &avail_disklabels[inst_disk]);
|
||||||
|
clear();
|
||||||
|
} else {
|
||||||
|
abort_installation("");
|
||||||
|
ok = 1;
|
||||||
|
ready = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default_disklabel(&avail_disklabels[inst_disk],
|
||||||
|
mbr->dospart[inst_part].dp_size,
|
||||||
|
mbr->dospart[inst_part].dp_start);
|
||||||
build_bootblocks(&avail_disklabels[inst_disk]);
|
build_bootblocks(&avail_disklabels[inst_disk]);
|
||||||
write_bootblocks(avail_fds[inst_disk],
|
|
||||||
bootarea->dospart[inst_part].dp_start,
|
if (ready) {
|
||||||
avail_disklabels[inst_disk].d_bbsize);
|
if (dialog_yesno(title, "We are now ready to format the hard disk for FreeBSD.\n\nSome or all of the disk will be overwritten during this process.\n\nAre you sure you wish to proceed ?", 10, 75)) {
|
||||||
|
abort_installation("");
|
||||||
|
ready = 0;
|
||||||
|
}
|
||||||
|
clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write master boot record and bootblocks */
|
||||||
|
write_mbr(avail_fds[inst_disk], mbr);
|
||||||
|
write_bootblocks(avail_fds[inst_disk],
|
||||||
|
mbr->dospart[inst_part].dp_start,
|
||||||
|
avail_disklabels[inst_disk].d_bbsize);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
read_mbr(avail_fds[inst_disk], mbr);
|
||||||
|
show_mbr(mbr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* close all the open disks */
|
/* close all the open disks */
|
||||||
for (i=0; i < no_disks; i++)
|
for (i=0; i < no_disks; i++)
|
||||||
if (close(avail_fds[i]) == -1) {
|
if (close(avail_fds[i]) == -1) {
|
||||||
@ -676,12 +741,20 @@ main(int argc, char **argv)
|
|||||||
setlogin("root");
|
setlogin("root");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /etc/termcap.small used, if TERM undefined */
|
|
||||||
if (set_termcap() == -1)
|
if (set_termcap() == -1)
|
||||||
fatal("Can't find terminal entry\n");
|
fatal("Can't find terminal entry\n");
|
||||||
|
|
||||||
if (alloc_memory() == -1)
|
if (alloc_memory() == -1)
|
||||||
fatal("Couldn't allocate memory\n");
|
fatal("Couldn't allocate memory\n");
|
||||||
|
|
||||||
|
if (uname(&utsname) == -1) {
|
||||||
|
/* Fake uname entry */
|
||||||
|
bcopy("FreeBSD", utsname.sysname, strlen("FreeBSD"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX - libdialog has particularly bad return value checking */
|
||||||
init_dialog();
|
init_dialog();
|
||||||
|
/* If we haven't crashed I guess dialog is running ! */
|
||||||
dialog_active = 1;
|
dialog_active = 1;
|
||||||
|
|
||||||
strcpy(scratch, "/etc/");
|
strcpy(scratch, "/etc/");
|
||||||
@ -711,5 +784,5 @@ main(int argc, char **argv)
|
|||||||
default:
|
default:
|
||||||
fatal("Unknown installation status");
|
fatal("Unknown installation status");
|
||||||
}
|
}
|
||||||
leave_sysinstall();
|
exit_sysinstall();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user