Fix all the bugs introduced by the source shuffle.

All the mbr code now seems to be working. We can build a basic
unix disklabel in any existing DOS partition while retaining the
existing mbr bootcode or we can install to the whole disk which
puts FreeBSD's boot code into the MBR and creates a clean MBR
partition table with FreeBSD in partition 0 taking up the whole disk.
This commit is contained in:
Paul Richards 1994-10-21 18:08:33 +00:00
parent d60b2c616a
commit b4740339e8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=3757
8 changed files with 195 additions and 120 deletions

View File

@ -8,7 +8,7 @@ SRCS = stage1.c dkcksum.c bootarea.c mbr.c \
utils.c termcap.c exec.c \
stage0.c stage2.c stage3.c main.c
CFLAGS += -Wall
CFLAGS += -Wall -g
LDADD = -ldialog -lncurses -lmytinfo
DPADD = ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO}

View File

@ -23,16 +23,16 @@
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <dialog.h>
#include "mbr.h"
#include "bootarea.h"
#include "sysinstall.h"
char boot1[] = BOOT1;
char boot2[] = BOOT2;
extern char *bootblocks;
extern struct mbr *mbr;
extern char boot1[];
extern char boot2[];
int
enable_label(int fd)
@ -88,15 +88,17 @@ build_bootblocks(struct disklabel *label)
int fd;
sprintf(scratch, "\nLoading boot code from %s\n", boot1);
dialog_msgbox(TITLE, scratch, 5, 60, 0);
fd = open(boot1, O_RDONLY);
if (fd < 0) {
sprintf(errmsg, "Couldn't open boot file %s\n", boot1);
return(-1);
}
if (read(fd, bootblocks, (int)label->d_secsize) < 0) {
if (read(fd, bootblocks, MBRSIZE) < 0) {
sprintf(errmsg, "Couldn't read from boot file %s\n", boot1);
return(-1);
return(-1);
}
if (close(fd) == -1) {
@ -104,14 +106,18 @@ build_bootblocks(struct disklabel *label)
return(-1);
}
dialog_clear();
sprintf(scratch, "\nLoading boot code from %s\n", boot1);
dialog_msgbox(TITLE, scratch, 5, 60, 0);
fd = open(boot2, O_RDONLY);
if (fd < 0) {
sprintf(errmsg, "Couldn't open boot file %s\n", boot2);
return(-1);
}
if (read(fd, &bootblocks[label->d_secsize],
(int)(label->d_bbsize - label->d_secsize)) < 0) {
if (read(fd, &bootblocks[MBRSIZE],
(int)(label->d_bbsize - MBRSIZE)) < 0) {
sprintf(errmsg, "Couldn't read from boot file %s\n", boot2);
return(-1);
}
@ -121,10 +127,12 @@ build_bootblocks(struct disklabel *label)
return(-1);
}
/* Write mbr partition table into bootblocks */
/* Copy DOS partition area into bootblocks */
bcopy(mbr->dospart, &bootblocks[DOSPARTOFF],
sizeof(struct dos_partition) * NDOSPART);
sizeof(struct dos_partition) * 4);
dialog_clear();
/* Write the disklabel into the bootblocks */

View File

@ -12,8 +12,8 @@
* its use.
*/
#define BOOT1 "/usr/mdec/sdboot"
#define BOOT2 "/usr/mdec/bootsd"
#define BOOT1 "/stand/sdboot"
#define BOOT2 "/stand/bootsd"
/* XXX -- calculate these, this is nasty */
#define DEFFSIZE 1024

View File

@ -13,17 +13,20 @@
*/
#include <stdio.h>
#include <unistd.h>
#include <dialog.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/disklabel.h>
#include <sys/uio.h>
#include <unistd.h>
#include <dialog.h>
#include "mbr.h"
#include "sysinstall.h"
extern struct mbr *mbr;
extern char *errmsg;
extern int inst_part;
extern int whole_disk;
struct part_type part_types[] = PARTITION_TYPES
@ -50,7 +53,7 @@ read_mbr(int fd, struct mbr *mbr)
sprintf(errmsg, "Couldn't seek for master boot record read\n");
return(-1);
}
if (read(fd, &(mbr->bootcode), 512) == -1) {
if (read(fd, &(mbr->bootcode), MBRSIZE) == -1) {
sprintf(errmsg, "Failed to read master boot record\n");
return(-1);
}
@ -70,11 +73,17 @@ write_mbr(int fd, struct mbr *mbr)
return(-1);
}
if (enable_label(fd) == -1)
return(-1);
if (write(fd, mbr->bootcode, MBRSIZE) == -1) {
sprintf(errmsg, "Failed to write master boot record\n");
return(-1);
}
if(disable_label(fd) == -1)
return(-1);
return(0);
}
@ -97,20 +106,20 @@ show_mbr(struct mbr *mbr)
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)",
mvwprintw(window, y+1, x, "Starting at (C%d, H%d, S%d)",
mbr->dospart[(i*2)+j].dp_scyl,
mbr->dospart[(i*2)+j].dp_shd,
mbr->dospart[(i*2)+j].dp_ssect,
mbr->dospart[(i*2)+j].dp_scyl);
mbr->dospart[(i*2)+j].dp_ssect);
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+3, x, "Ending at (C%d, H%d, S%d)",
mbr->dospart[(i*2)+j].dp_ecyl,
mbr->dospart[(i*2)+j].dp_ehd,
mbr->dospart[(i*2)+j].dp_esect);
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);
mvwprintw(window, y+5, x, "Size (in sectors) %ld", mbr->dospart[(i*2)+j].dp_size);
}
}
refresh();
@ -119,14 +128,40 @@ show_mbr(struct mbr *mbr)
key = wgetch(window);
delwin(window);
dialog_clear();
}
void
clear_mbr(struct mbr *mbr)
int
clear_mbr(struct mbr *mbr, char *bootcode)
{
int i;
int fd;
/*
* If installing to the whole disk
* then clobber any existing bootcode.
*/
sprintf(scratch, "\nLoading MBR code from %s\n", bootcode);
dialog_msgbox(TITLE, scratch, 5, 60, 0);
fd = open(bootcode, O_RDONLY);
if (fd < 0) {
sprintf(errmsg, "Couldn't open boot file %s\n", bootcode);
return(-1);
}
if (read(fd, mbr->bootcode, MBRSIZE) < 0) {
sprintf(errmsg, "Couldn't read from boot file %s\n", bootcode);
return(-1);
}
if (close(fd) == -1) {
sprintf(errmsg, "Couldn't close boot file %s\n", bootcode);
return(-1);
}
/* Create an empty partition table */
for (i=0; i < NDOSPART; i++) {
mbr->dospart[i].dp_flag = 0;
mbr->dospart[i].dp_shd = 0;
@ -139,47 +174,49 @@ clear_mbr(struct mbr *mbr)
mbr->dospart[i].dp_start = 0;
mbr->dospart[i].dp_size = 0;
}
mbr->magic = MBR_MAGIC;
dialog_clear();
return(0);
}
int
build_mbr(struct mbr *mbr, struct disklabel *label)
build_mbr(struct mbr *mbr, char *bootcode, struct disklabel *lb)
{
int i;
struct dos_partition *dp = &mbr->dospart[inst_part];
/*
* This is the biggie, need to spend some time getting all
* the different possibilities sorted out.
*/
if (inst_part == -1) {
if (whole_disk) {
/* 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);
}
if (clear_mbr(mbr, bootcode) == -1)
return(-1);
dp->dp_scyl = 0;
dp->dp_shd = 1;
dp->dp_ssect = 1;
dp->dp_ecyl = lb->d_ncylinders - 1;
dp->dp_ehd = lb->d_ntracks - 1;
dp->dp_esect = lb->d_nsectors;
dp->dp_start = (dp->dp_scyl * lb->d_ntracks * lb->d_nsectors) +
(dp->dp_shd * lb->d_nsectors) +
dp->dp_ssect - 1;
dp->dp_size = (lb->d_nsectors * lb->d_ntracks * lb->d_ncylinders) - dp->dp_start;
}
/* Validate partition - XXX need to spend some time making this robust */
if (!dp->dp_start) {
strcpy(errmsg, "The start address of the selected partition is 0\n");
return(-1);
}
/* 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);
dp->dp_typ = DOSPTYP_386BSD;
dp->dp_flag = ACTIVE;
return(0);
}
void

View File

@ -78,6 +78,6 @@ 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 int clear_mbr(struct mbr *, char *);
extern void edit_mbr(struct mbr *, struct disklabel *);
extern int build_mbr(struct mbr *, struct disklabel *);
extern int build_mbr(struct mbr *, char *, struct disklabel *);

View File

@ -26,10 +26,7 @@
#include <sys/disklabel.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <ufs/ffs/fs.h>
#include <machine/console.h>
@ -49,7 +46,8 @@ struct mbr *mbr;
int no_disks = 0;
int inst_disk = 0;
int inst_part = 0;
int custom_install;
int whole_disk = 0;
int custom_install = 0;
int dialog_active = 0;
void exit_sysinstall();
@ -57,8 +55,9 @@ void exit_prompt();
extern char *part_type(int);
extern int disk_size(int);
/* To make the binary as small as possible these should be malloc'd */
char selection[30];
char boot1[] = BOOT1;
char boot2[] = BOOT2;
int
alloc_memory()
@ -184,7 +183,8 @@ select_disk()
}
if (dialog_menu("FreeBSD Installation", scratch, 10, 75, 5, no_disks, options, selection)) {
sprintf(scratch,"You did not select a valid disk");
dialog_clear();
sprintf(scratch,"\n\n\nYou did not select a valid disk.\n\n");
AskAbort(scratch);
valid = 0;
}
@ -216,18 +216,24 @@ select_partition(int disk)
if (dialog_menu(TITLE,
scratch, 10, 75, 5, 5, options, selection)) {
sprintf(scratch,"You did not select a valid partition");
dialog_clear();
AskAbort(scratch);
valid = 0;
}
dialog_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))
choice = atoi(selection) - 1;
if (choice == -1) {
whole_disk = 1;
choice = 0;
if (dialog_yesno(TITLE, "\n\nInstalling to the whole disk will erase all its current data.\n\nAre you sure you want to do this?", 10, 75)) {
valid = 0;
whole_disk = 0;
}
}
dialog_clear();
} while (!valid);
return(atoi(selection) - 1);
return(choice);
}
void
@ -237,31 +243,31 @@ stage1()
int ok = 0;
int ready = 0;
query_disks();
while (!ready) {
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);
sprintf(scratch, "The following error occured will trying\nto read the master boot record:\n\n%s\nIn order to install FreeBSD a new master boot record\nwill have to be written which will mean all current\ndata on the hard disk will be lost.", errmsg);
ok = 0;
while (!ok) {
AskAbort(scratch);
if (!dialog_yesno(TITLE, "Are you sure you wish to proceed?",
10, 75)) {
dialog_clear();
clear_mbr(mbr);
if (clear_mbr(mbr, boot1) == -1) {
sprintf(scratch, "\n\nCouldn't create new master boot record.\n\n%s", errmsg);
Fatal(scratch);;
}
ok = 1;
}
dialog_clear();
}
}
if (custom_install)
if (!dialog_yesno(TITLE, "Do you wish to edit the DOS partition table?",
10, 75)) {
@ -269,33 +275,42 @@ stage1()
edit_mbr(mbr, &avail_disklabels[inst_disk]);
}
dialog_clear();
inst_part = select_partition(inst_disk);
ok = 0;
while (!ok) {
if (build_mbr(mbr, &avail_disklabels[inst_disk]))
if (build_mbr(mbr, boot1, &avail_disklabels[inst_disk]) != -1) {
ready = 1;
ok = 1;
else {
sprintf(scratch, "The DOS partition table is inconsistent.\n\n%s\n\nDo you wish to edit it by hand?", errmsg);
} else {
sprintf(scratch, "The DOS partition table is inconsistent.\n\n%s\nDo you wish to edit it by hand?", errmsg);
if (!dialog_yesno(TITLE, scratch, 10, 75)) {
edit_mbr(mbr, &avail_disklabels[inst_disk]);
dialog_clear();
edit_mbr(mbr, &avail_disklabels[inst_disk]);
} else {
AskAbort("");
dialog_clear();
AskAbort("Installation cannot proceed without\na valid master boot record\n");
ok = 1;
ready = 0;
}
}
dialog_clear();
}
default_disklabel(&avail_disklabels[inst_disk],
if (ready) {
default_disklabel(&avail_disklabels[inst_disk],
mbr->dospart[inst_part].dp_size,
mbr->dospart[inst_part].dp_start);
build_bootblocks(&avail_disklabels[inst_disk]);
if (build_bootblocks(&avail_disklabels[inst_disk]) == -1)
Fatal(errmsg);
}
/* ready could have been reset above */
if (ready) {
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)) {
AskAbort("");
dialog_clear();
AskAbort("Do you want to quit?");
ready = 0;
}
dialog_clear();
@ -303,15 +318,12 @@ stage1()
}
/* Write master boot record and bootblocks */
write_mbr(avail_fds[inst_disk], mbr);
write_bootblocks(avail_fds[inst_disk],
if (write_mbr(avail_fds[inst_disk], mbr) == -1)
Fatal(errmsg);
if (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
avail_disklabels[inst_disk].d_bbsize) == -1)
Fatal(errmsg);
/* close all the open disks */
for (i=0; i < no_disks; i++)
@ -320,6 +332,4 @@ stage1()
strerror(errno));
Fatal(errmsg);
}
}

View File

@ -29,22 +29,6 @@
#define COPYRIGHT_FILE "/COPYRIGHT"
#define README_FILE "/README"
#define STATUSFILE "sysinstall.stat"
#define NOT_INSTALLED 0
#define DISK_READY 1
#define INSTALLED_BASE 2
struct sysinstall
{
char media[90];
int status;
char seq_name[64];
int seq_size;
int seq_no;
char archive[64];
char root_dev[90];
};
#ifndef EXTERN
# define EXTERN extern
#endif
@ -62,12 +46,14 @@ extern struct disklabel *avail_disklabels;
extern u_short dkcksum(struct disklabel *);
/* utils.c */
void Abort __P((void));
void ExitSysinstall __P((void));
void TellEm __P((char *fmt, ...));
void stage0 __P((void));
void *Malloc __P((size_t size));
char *StrAlloc __P((char *str));
void Fatal __P((char *fmt, ...));
int AskAbort __P((char *fmt, ...));
void AskAbort __P((char *fmt, ...));
void MountUfs __P((char *device, char *prefix, char *mountpoint, int do_mkdir));
void Mkdir __P((char *path));

View File

@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $Id: utils.c,v 1.5 1994/10/21 02:14:54 phk Exp $
* $Id: utils.c,v 1.6 1994/10/21 04:43:07 ache Exp $
*
*/
@ -23,6 +23,7 @@
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/reboot.h>
#include "sysinstall.h"
@ -36,6 +37,7 @@ TellEm(char *fmt, ...)
vsnprintf(p, 2048, fmt, ap);
va_end(ap);
dialog_msgbox("Progress", p, 3, 75, 0);
dialog_clear();
free(p);
}
@ -43,36 +45,68 @@ void
Fatal(char *fmt, ...)
{
char *p;
int i = errno;
va_list ap;
p = Malloc(2048);
va_start(ap,fmt);
vsnprintf(p, 2048, fmt, ap);
va_end(ap);
sprintf(p+strlen(p),"\nErrno= %d, %s.",i,strerror(i));
if (dialog_active) {
dialog_msgbox("Fatal", p, 12, 75, 1);
end_dialog();
} else
fprintf(stderr, "Fatal -- %s", p);
free(p);
exit(7);
ExitSysinstall();
}
int
void
AskAbort(char *fmt, ...)
{
char *p;
va_list ap;
int i;
p = Malloc(2048);
va_start(ap,fmt);
vsnprintf(p, 2048, fmt, ap);
va_end(ap);
i = dialog_yesno("Abort", p, 12, 75);
strcat(p, "\n\nDo you wish to abort the installation?");
if (!dialog_yesno("Abort", p, 15, 60)) {
dialog_clear();
Abort();
}
dialog_clear();
free(p);
return i;
}
void
Abort()
{
if (dialog_yesno("Exit sysinstall","\n\nAre you sure you want to quit?",
10, 40)) {
dialog_clear();
return;
}
ExitSysinstall();
}
void
ExitSysinstall()
{
if (getpid() == 1) {
clear();
if (reboot(RB_AUTOBOOT) == -1)
if (dialog_active) {
dialog_clear();
dialog_msgbox(TITLE, "\n\nCan't reboot machine -- hit reset button",
5,30,0);
} else
fprintf(stderr, "Can't reboot the machine -- hit the reset button");
while(1);
} else
clear();
refresh();
end_dialog();
exit(0);
}
void *
@ -121,7 +155,7 @@ MountUfs(char *device, char *prefix, char *mountpoint, int do_mkdir)
TellEm("mount /dev/%s /mnt%s",dbuf,pbuf);
ufsargs.fspec = dbuf;
if (mount(MOUNT_UFS,pbuf, 0, (caddr_t) &ufsargs) == -1) {
Fatal("Error mounting %s on : %s\n",
Fatal("Error mounting %s on %s : %s\n",
dbuf, pbuf, strerror(errno));
}
}