aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libdisk/Makefile22
-rw-r--r--lib/libdisk/blocks.c10
-rw-r--r--lib/libdisk/chunk.c5
-rw-r--r--lib/libdisk/create_chunk.c11
-rw-r--r--lib/libdisk/disk.c59
-rw-r--r--lib/libdisk/libdisk.h46
-rw-r--r--lib/libdisk/rules.c76
-rw-r--r--lib/libdisk/tst01.c26
-rw-r--r--lib/libdisk/write_disk.c158
-rw-r--r--release/libdisk/Makefile22
-rw-r--r--release/libdisk/blocks.c10
-rw-r--r--release/libdisk/chunk.c5
-rw-r--r--release/libdisk/create_chunk.c11
-rw-r--r--release/libdisk/disk.c59
-rw-r--r--release/libdisk/libdisk.h46
-rw-r--r--release/libdisk/rules.c76
-rw-r--r--release/libdisk/tst01.c26
-rw-r--r--release/libdisk/write_disk.c158
18 files changed, 720 insertions, 106 deletions
diff --git a/lib/libdisk/Makefile b/lib/libdisk/Makefile
index 4128a2966cf8..18d1cbae34cd 100644
--- a/lib/libdisk/Makefile
+++ b/lib/libdisk/Makefile
@@ -1,14 +1,32 @@
.PATH: /usr/src/sbin/disklabel
OBJS= tst01.o blocks.o disklabel.o dkcksum.o chunk.o disk.o change.o \
- create_chunk.o rules.o write_disk.o
+ create_chunk.o rules.o write_disk.o data.o
CFLAGS+= -Wall -g
test: tst01
cp tst01 /0
./tst01 wd1
+fd: tst01
+ -umount /dev/fd1
+ -umount /mnt
+ mount /dev/fd1 /mnt
+ strip tst01
+ gzip < tst01 > /mnt/stand/disklayout
+ chmod 755 /mnt/stand/disklayout
+ -umount /mnt
+
+BOOTS=/usr/mdec
+data.o:
+ file2c 'const unsigned char boot1[] = {' '};' \
+ < ${BOOTS}/boot1 > tmp.c
+ file2c 'const unsigned char boot2[] = {' '};' \
+ < ${BOOTS}/boot2 >> tmp.c
+ cc ${CFLAGS} -o data.o -c tmp.c
+
tst01: ${OBJS}
- cc ${CFLAGS} -static -o tst01 ${OBJS} -lreadline -ltermcap
+ #cc ${CFLAGS} -DREADLINE -static -o tst01 ${OBJS} -lreadline -ltermcap
+ cc ${CFLAGS} -static -o tst01 ${OBJS}
clean:
rm -f *.o *.core tst01
diff --git a/lib/libdisk/blocks.c b/lib/libdisk/blocks.c
index 65d0dae72e5d..85a9c44cf707 100644
--- a/lib/libdisk/blocks.c
+++ b/lib/libdisk/blocks.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id$
+ * $Id: blocks.c,v 1.2 1995/04/29 01:55:17 phk Exp $
*
*/
@@ -31,3 +31,11 @@ read_block(int fd, daddr_t block)
return foo;
}
+void
+write_block(int fd, daddr_t block, void *foo)
+{
+ if (-1 == lseek(fd,block * 512,SEEK_SET))
+ err(1,"lseek");
+ if (512 != write(fd,foo, 512))
+ err(1,"write");
+}
diff --git a/lib/libdisk/chunk.c b/lib/libdisk/chunk.c
index e81c646ae3b3..9b3a6bd46cf2 100644
--- a/lib/libdisk/chunk.c
+++ b/lib/libdisk/chunk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: chunk.c,v 1.2 1995/04/29 01:55:19 phk Exp $
+ * $Id: chunk.c,v 1.3 1995/04/29 04:00:54 phk Exp $
*
*/
@@ -190,7 +190,7 @@ Add_Chunk(struct disk *d, u_long offset, u_long size, char *name, chunk_e type,
c2->size = c1->size = size;
c2->end = c1->end = end;
c1->name = strdup(name);
- c2->name = strdup(name);
+ c2->name = strdup("-");
c1->type = type;
c2->type = unused;
c1->flags = flags;
@@ -302,6 +302,7 @@ Delete_Chunk(struct disk *d, struct chunk *c)
Free_Chunk(c3);
goto scan;
}
+ Fixup_Names(d);
return 0;
}
diff --git a/lib/libdisk/create_chunk.c b/lib/libdisk/create_chunk.c
index 82c0082d82c2..27652e645f65 100644
--- a/lib/libdisk/create_chunk.c
+++ b/lib/libdisk/create_chunk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: create_chunk.c,v 1.2 1995/04/29 01:55:20 phk Exp $
+ * $Id: create_chunk.c,v 1.3 1995/04/29 07:21:10 phk Exp $
*
*/
@@ -24,15 +24,16 @@
void
Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
{
- struct chunk *c1, *c2, *c3;
+ struct chunk *c1, *c3;
int j;
char *p=0;
+ if (!strcmp(c->name, "X")) return;
for (c1 = c->part; c1 ; c1 = c1->next) {
if (c1->type == unused) continue;
if (c1->type == reserved) continue;
if (strcmp(c1->name, "X")) continue;
- for(j=0;j<=8;j++) {
+ for(j=0;j<8;j++) {
if (j == 2)
continue;
p = malloc(12);
@@ -56,7 +57,7 @@ Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
void
Fixup_Extended_Names(struct disk *d, struct chunk *c)
{
- struct chunk *c1, *c2, *c3;
+ struct chunk *c1, *c3;
int j;
char *p=0;
@@ -127,6 +128,8 @@ int
Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
{
int i;
+ u_long l1,l2,end = offset + size;
+
i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
Fixup_Names(d);
return i;
diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c
index 24d2657036aa..fb483e0aedbb 100644
--- a/lib/libdisk/disk.c
+++ b/lib/libdisk/disk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: disk.c,v 1.4 1995/04/29 04:50:37 phk Exp $
+ * $Id: disk.c,v 1.5 1995/04/29 07:21:11 phk Exp $
*
*/
@@ -40,21 +40,24 @@ Int_Open_Disk(char *name, u_long size)
struct disklabel dl;
char device[64];
struct disk *d;
+ struct dos_partition *dp;
+ void *p;
strcpy(device,"/dev/r");
strcat(device,name);
+ d = (struct disk *)malloc(sizeof *d);
+ if(!d) err(1,"malloc failed");
+ memset(d,0,sizeof *d);
+
fd = open(device,O_RDONLY);
if (fd < 0) {
warn("open(%s) failed",device);
return 0;
}
- i = ioctl(fd,DIOCGDINFO,&dl);
- if (i < 0) {
- warn("DIOCGDINFO(%s) failed",device);
- close(fd);
- return 0;
- }
+
+ memset(&dl,0,sizeof dl);
+ ioctl(fd,DIOCGDINFO,&dl);
i = ioctl(fd,DIOCGSLICEINFO,&ds);
if (i < 0) {
warn("DIOCGSLICEINFO(%s) failed",device);
@@ -62,18 +65,27 @@ Int_Open_Disk(char *name, u_long size)
return 0;
}
- d = (struct disk *)malloc(sizeof *d);
- if(!d) err(1,"malloc failed");
+ if (!size)
+ size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
- memset(d,0,sizeof *d);
+ p = read_block(fd,0);
+ dp = (struct dos_partition*)(p+DOSPARTOFF);
+ for(i=0;i<NDOSPART;i++) {
+ if (dp->dp_start >= size) continue;
+ if (dp->dp_start+dp->dp_size >= size) continue;
+ if (!dp->dp_size) continue;
+
+ if (dp->dp_typ == DOSPTYP_ONTRACK)
+ d->flags |= DISK_ON_TRACK;
+
+ }
+ free(p);
d->bios_sect = dl.d_nsectors;
d->bios_hd = dl.d_ntracks;
d->name = strdup(name);
- if (!size)
- size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
if (dl.d_ntracks && dl.d_nsectors)
d->bios_cyl = size/(dl.d_ntracks*dl.d_nsectors);
@@ -85,7 +97,7 @@ Int_Open_Disk(char *name, u_long size)
if (Add_Chunk(d, 0, 1, "-",reserved,0,0))
warn("Failed to add MBR chunk");
- for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
+ for(i=BASE_SLICE;i < 12 && i<ds.dss_nslices;i++) {
char sname[20];
chunk_e ce;
u_long flags=0;
@@ -132,18 +144,21 @@ Int_Open_Disk(char *name, u_long size)
if (!dl->d_partitions[j].p_size)
continue;
if (Add_Chunk(d,
- dl->d_partitions[j].p_offset,
+ dl->d_partitions[j].p_offset +
+ ds.dss_slices[i].ds_offset,
dl->d_partitions[j].p_size,
pname,part,0,0))
- warn("Failed to add chunk for partition %c",j + 'a');
+ warn(
+ "Failed to add chunk for partition %c [%lu,%lu]",
+ j + 'a',dl->d_partitions[j].p_offset,dl->d_partitions[j].p_size);
}
sprintf(pname,"%sd",sname);
- if (!dl->d_partitions[3].p_size)
- continue;
- Add_Chunk(d,
- dl->d_partitions[3].p_offset,
- dl->d_partitions[3].p_size,
- pname,part,0,0);
+ if (dl->d_partitions[3].p_size)
+ Add_Chunk(d,
+ dl->d_partitions[3].p_offset +
+ ds.dss_slices[i].ds_offset,
+ dl->d_partitions[3].p_size,
+ pname,part,0,0);
}
free(dl);
}
@@ -159,6 +174,8 @@ Debug_Disk(struct disk *d)
printf(" flags=%lx",d->flags);
printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
printf(" bios_geom=%lu/%lu/%lu\n",d->bios_cyl,d->bios_hd,d->bios_sect);
+ printf(" boot1=%p, boot2=%p, bootmgr=%p\n",
+ d->boot1,d->boot2,d->bootmgr);
Debug_Chunk(d->chunks);
}
diff --git a/lib/libdisk/libdisk.h b/lib/libdisk/libdisk.h
index a84481450eb0..827fd4bfbba1 100644
--- a/lib/libdisk/libdisk.h
+++ b/lib/libdisk/libdisk.h
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: libdisk.h,v 1.4 1995/04/29 04:50:38 phk Exp $
+ * $Id: libdisk.h,v 1.5 1995/04/29 07:21:11 phk Exp $
*
*/
@@ -22,7 +22,6 @@ struct disk {
char *name;
u_long flags;
# define DISK_ON_TRACK 1
-# define DISK_REAL_GEOM 2
u_long real_cyl;
u_long real_hd;
u_long real_sect;
@@ -44,9 +43,6 @@ struct chunk {
char *name;
chunk_e type;
int subtype;
-# define SUBTYPE_BSD_FS 1
-# define SUBTYPE_BSD_SWAP 2
-# define SUBTYPE_BSD_UNUSED 3
u_long flags;
# define CHUNK_PAST_1024 1
/* this chunk cannot be booted from */
@@ -142,6 +138,40 @@ Write_Disk(struct disk *d);
/* Write all the MBRs, disklabels, bootblocks and boot managers
*/
+int
+Cyl_Aligned(struct disk *d, u_long offset);
+ /* Check if offset is aligned on a cylinder according to the
+ * bios geometry
+ */
+
+u_long
+Next_Cyl_Aligned(struct disk *d, u_long offset);
+ /* Round offset up to next cylinder according to the bios-geometry
+ */
+
+u_long
+Prev_Cyl_Aligned(struct disk *d, u_long offset);
+ /* Round offset down to previous cylinder according to the bios-
+ * geometry
+ */
+
+int
+Track_Aligned(struct disk *d, u_long offset);
+ /* Check if offset is aligned on a track according to the
+ * bios geometry
+ */
+
+u_long
+Next_Track_Aligned(struct disk *d, u_long offset);
+ /* Round offset up to next track according to the bios-geometry
+ */
+
+u_long
+Prev_Track_Aligned(struct disk *d, u_long offset);
+ /* Check if offset is aligned on a track according to the
+ * bios geometry
+ */
+
/*
* Implementation details >>> DO NOT USE <<<
*/
@@ -152,11 +182,9 @@ struct chunk * Clone_Chunk(struct chunk *);
int Add_Chunk(struct disk *, u_long , u_long , char *, chunk_e, int , u_long);
void Bios_Limit_Chunk(struct chunk *, u_long);
void * read_block(int, daddr_t );
+void write_block(int fd, daddr_t block, void *foo);
struct disklabel * read_disklabel(int, daddr_t);
u_short dkcksum(struct disklabel *);
-int Aligned(struct disk *d, u_long offset);
-u_long Next_Aligned(struct disk *d, u_long offset);
-u_long Prev_Aligned(struct disk *d, u_long offset);
struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e);
struct disk * Int_Open_Disk(char *name, u_long size);
@@ -181,6 +209,8 @@ struct disk * Int_Open_Disk(char *name, u_long size);
* Make Create_DWIM().
*
* Make Is_Unchanged(struct disk *d1, struct chunk *c1)
+ *
+ * Make Set_Active_Slice()
*
*Sample output from tst01:
*
diff --git a/lib/libdisk/rules.c b/lib/libdisk/rules.c
index 9a53b4ef3bd2..ef50415e15ba 100644
--- a/lib/libdisk/rules.c
+++ b/lib/libdisk/rules.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: rules.c,v 1.2 1995/04/29 04:00:56 phk Exp $
+ * $Id: rules.c,v 1.3 1995/04/29 07:21:12 phk Exp $
*
*/
@@ -21,7 +21,7 @@
#include "libdisk.h"
int
-Aligned(struct disk *d, u_long offset)
+Track_Aligned(struct disk *d, u_long offset)
{
if (!d->bios_sect)
return 1;
@@ -31,7 +31,7 @@ Aligned(struct disk *d, u_long offset)
}
u_long
-Prev_Aligned(struct disk *d, u_long offset)
+Prev_Track_Aligned(struct disk *d, u_long offset)
{
if (!d->bios_sect)
return offset;
@@ -39,11 +39,37 @@ Prev_Aligned(struct disk *d, u_long offset)
}
u_long
-Next_Aligned(struct disk *d, u_long offset)
+Next_Track_Aligned(struct disk *d, u_long offset)
{
if (!d->bios_sect)
return offset;
- return Prev_Aligned(d,offset + d->bios_sect);
+ return Prev_Track_Aligned(d,offset + d->bios_sect);
+}
+
+int
+Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return 1;
+ if (offset % (d->bios_sect * d->bios_hd))
+ return 0;
+ return 1;
+}
+
+u_long
+Prev_Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return offset;
+ return (offset / (d->bios_sect*d->bios_hd)) * d->bios_sect * d->bios_hd;
+}
+
+u_long
+Next_Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return offset;
+ return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd));
}
/*
@@ -58,9 +84,13 @@ Rule_000(struct disk *d, struct chunk *c, char *msg)
if (c->type != whole)
return;
- for (i=0, c1=c->part; c1; c1=c1->next)
- if (c1->type != unused)
- i++;
+ for (i=0, c1=c->part; c1; c1=c1->next) {
+ if (c1->type != reserved)
+ continue;
+ if (c1->type != reserved)
+ continue;
+ i++;
+ }
if (i <= NDOSPART)
return;
sprintf(msg+strlen(msg),
@@ -86,13 +116,13 @@ Rule_001(struct disk *d, struct chunk *c, char *msg)
continue;
if (c1->type == unused)
continue;
- if (!Aligned(d,c1->offset))
+ if (!Track_Aligned(d,c1->offset))
sprintf(msg+strlen(msg),
"chunk '%s' [%ld..%ld] does not start on a track boundary\n",
c1->name,c1->offset,c1->end);
- if (c->end != c1->end && !Aligned(d,c1->end+1))
+ if (c->end != c1->end && !Cyl_Aligned(d,c1->end+1))
sprintf(msg+strlen(msg),
- "chunk '%s' [%ld..%ld] does not end on a track boundary\n",
+ "chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n",
c1->name,c1->offset,c1->end);
}
}
@@ -143,6 +173,29 @@ Rule_003(struct disk *d, struct chunk *c, char *msg)
}
}
+/*
+ * Rule#4:
+ * Max seven 'part' as children of 'freebsd'
+ */
+void
+Rule_004(struct disk *d, struct chunk *c, char *msg)
+{
+ int i;
+ struct chunk *c1;
+
+ if (c->type != freebsd)
+ return;
+ for (i=0, c1=c->part; c1; c1=c1->next) {
+ if (c1->type != part)
+ continue;
+ i++;
+ }
+ if (i > 7) {
+ sprintf(msg+strlen(msg),
+ "Max seven 'part' allowed as child of 'freebsd'\n");
+ }
+}
+
void
Check_Chunk(struct disk *d, struct chunk *c, char *msg)
{
@@ -150,6 +203,7 @@ Check_Chunk(struct disk *d, struct chunk *c, char *msg)
Rule_001(d,c,msg);
Rule_002(d,c,msg);
Rule_003(d,c,msg);
+ Rule_004(d,c,msg);
if (c->part)
Check_Chunk(d,c->part,msg);
if (c->next)
diff --git a/lib/libdisk/tst01.c b/lib/libdisk/tst01.c
index 4a866ba4d4b7..e175b5c59876 100644
--- a/lib/libdisk/tst01.c
+++ b/lib/libdisk/tst01.c
@@ -6,16 +6,19 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: tst01.c,v 1.4 1995/04/29 04:50:39 phk Exp $
+ * $Id: tst01.c,v 1.5 1995/04/29 07:21:13 phk Exp $
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
#include <err.h>
+#ifdef READLINE
#include <readline/readline.h>
#include <readline/history.h>
+#endif
#include <sys/types.h>
#include "libdisk.h"
@@ -26,6 +29,9 @@ main(int argc, char **argv)
{
struct disk *d,*db;
char myprompt[BUFSIZ];
+#ifndef READLINE
+ char input[BUFSIZ];
+#endif
char *p,*q=0;
char **cp,*cmds[200];
int ncmd,i;
@@ -36,7 +42,7 @@ main(int argc, char **argv)
}
d = Open_Disk(argv[1]);
if (!d)
- err(1,"Coudn't open disk %s",argv[1]);
+ err(1,"Couldn't open disk %s",argv[1]);
sprintf(myprompt,"%s %s> ",argv[0],argv[1]);
while(1) {
@@ -47,12 +53,18 @@ main(int argc, char **argv)
printf("%s",p);
free(p);
}
+#ifdef READLINE
if (q)
free(q);
q = p = readline(myprompt);
+#else
+ printf(myprompt);
+ fflush(stdout);
+ q = p = fgets(input,sizeof(input),stdin);
+#endif
if(!p)
break;
- for(cp = cmds; (*cp = strsep(&p, " \t")) != NULL;)
+ for(cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
if (**cp != '\0')
cp++;
ncmd = cp - cmds;
@@ -128,9 +140,16 @@ main(int argc, char **argv)
d = db;
continue;
}
+ if (!strcasecmp(*cmds,"boot")) {
+ extern u_char boot1[],boot2[];
+ Set_Boot_Blocks(d,boot1,boot2);
+ continue;
+ }
if (!strcasecmp(*cmds,"write")) {
printf("Write=%d\n",
Write_Disk(d));
+ Free_Disk(d);
+ d = Open_Disk(d->name);
continue;
}
if (strcasecmp(*cmds,"help"))
@@ -138,6 +157,7 @@ main(int argc, char **argv)
printf("CMDS:\n");
printf("\tallfreebsd\n");
printf("\tbios cyl hd sect\n");
+ printf("\tboot\n");
printf("\tcollapse [pointer]\n");
printf("\tcreate offset size enum subtype flags\n");
printf("\tdelete pointer\n");
diff --git a/lib/libdisk/write_disk.c b/lib/libdisk/write_disk.c
index aa7190503a0b..f39c67df8154 100644
--- a/lib/libdisk/write_disk.c
+++ b/lib/libdisk/write_disk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id$
+ * $Id: write_disk.c,v 1.1 1995/04/29 07:21:14 phk Exp $
*
*/
@@ -25,10 +25,166 @@
#define DOSPTYP_EXTENDED 5
#define DOSPTYP_ONTRACK 84
+#define BBSIZE 8192
+
+#define WHERE(offset,disk) (disk->flags & DISK_ON_TRACK ? offset + 63 : offset)
+int
+Write_FreeBSD(int fd, struct disk *new, struct disk *old, struct chunk *c1)
+{
+ struct disklabel *dl;
+ struct chunk *c2;
+ int i,j;
+ void *p;
+ u_char buf[BBSIZE];
+
+ for(i=0;i<BBSIZE/512;i++) {
+ p = read_block(fd,i + c1->offset);
+ memcpy(buf+512*i,p,512);
+ free(p);
+ }
+ if(new->boot1)
+ memcpy(buf,new->boot1,512);
+
+ if(new->boot2)
+ memcpy(buf+512,new->boot2,BBSIZE-512);
+
+ dl = (struct disklabel *) (buf+512*LABELSECTOR+LABELOFFSET);
+ memset(dl,0,sizeof *dl);
+
+ printf("--> Write_FreeBSD()\n");
+
+ for(c2=c1->part;c2;c2=c2->next) {
+ if (c2->type == unused) continue;
+ if (c2->type == reserved) continue;
+ if (!strcmp(c2->name,"X")) continue;
+ j = c2->name[5] - 'a';
+ if (j < 0 || j >= MAXPARTITIONS || j == RAW_PART) {
+ warn("Weird parititon letter %c",c2->name[5]);
+ continue;
+ }
+ dl->d_partitions[j].p_size = c2->size;
+ dl->d_partitions[j].p_offset = c2->offset - c1->offset;
+
+ }
+
+ dl->d_bbsize = BBSIZE;
+
+ strcpy(dl->d_typename,c1->name);
+
+ dl->d_secperunit = new->chunks->size;
+ dl->d_secpercyl = new->real_cyl ? new->real_cyl : new->bios_cyl;
+ dl->d_ntracks = new->real_hd ? new->real_hd : new->bios_hd;
+ dl->d_nsectors = new->real_sect ? new->real_sect : new->bios_sect;
+
+ dl->d_npartitions = MAXPARTITIONS;
+
+ dl->d_type = new->name[0] == 's' ? DTYPE_SCSI : DTYPE_ESDI;
+ dl->d_partitions[RAW_PART].p_size = c1->size;
+ dl->d_partitions[RAW_PART].p_offset = 0;
+
+ dl->d_magic = DISKMAGIC;
+ dl->d_magic2 = DISKMAGIC;
+ dl->d_checksum = dkcksum(dl);
+
+ for(i=0;i<BBSIZE/512;i++) {
+ write_block(fd,WHERE(i + c1->offset,new),buf+512*i);
+ }
+
+ return 0;
+}
+
+int
+Write_Extended(int fd, struct disk *new, struct disk *old, struct chunk *c1)
+{
+ printf("--> Write_Extended()\n");
+ Print_Chunk(c1);
+ return 0;
+}
int
Write_Disk(struct disk *d1)
{
+ int fd,i,j;
+ struct disk *old = 0;
+ struct chunk *c1;
+ int ret = 0;
+ char device[64];
+ void *mbr;
+ struct dos_partition *dp;
+ int s[4];
+
+ strcpy(device,"/dev/r");
+ strcat(device,d1->name);
+
+ fd = open(device,O_RDWR);
+ if (fd < 0) {
+ warn("open(%s) failed",device);
+ return 1;
+ }
+
+ memset(s,0,sizeof s);
+ mbr = read_block(fd,0);
+ dp = (struct dos_partition*) (mbr + DOSPARTOFF);
+ for (c1=d1->chunks->part; c1 ; c1 = c1->next) {
+ if (c1->type == unused) continue;
+ if (c1->type == reserved) continue;
+ if (!strcmp(c1->name,"X")) continue;
+ if (c1->type == extended)
+ ret += Write_Extended(fd, d1,old,c1);
+ if (c1->type == freebsd)
+ ret += Write_FreeBSD(fd, d1,old,c1);
+ j = c1->name[4] - '1';
+ if (j < 0 || j > 3)
+ continue;
+ s[j]++;
+ dp[j].dp_start = c1->offset;
+ dp[j].dp_size = c1->size;
+
+ i = c1->offset;
+ if (i >= 1024*d1->bios_sect*d1->bios_hd)
+ i = 1024*d1->bios_sect*d1->bios_hd - 1;
+ dp[j].dp_ssect = i % d1->bios_sect;
+ i -= dp[j].dp_ssect;
+ i /= d1->bios_sect;
+ dp[j].dp_ssect++;
+ dp[j].dp_shd = i % d1->bios_hd;
+ i -= dp[j].dp_shd;
+ i /= d1->bios_hd;
+ dp[j].dp_scyl = i;
+
+ i = c1->end;
+ if (i >= 1024*d1->bios_sect*d1->bios_hd)
+ i = 1024*d1->bios_sect*d1->bios_hd - 1;
+ dp[j].dp_esect = i % d1->bios_sect;
+ i -= dp[j].dp_esect;
+ i /= d1->bios_sect;
+ dp[j].dp_esect++;
+ dp[j].dp_ehd = i % d1->bios_hd;
+ i -= dp[j].dp_ehd;
+ i /= d1->bios_hd;
+ dp[j].dp_ecyl = i;
+ switch (c1->type) {
+ case freebsd:
+ dp[j].dp_typ = 0xa5;
+ break;
+ case fat:
+ dp[j].dp_typ = 1;
+ break;
+ case extended:
+ dp[j].dp_typ = 5;
+ break;
+ case foo:
+ dp[j].dp_typ = - c1->subtype;
+ break;
+ }
+ }
+ for(i=0;i<NDOSPART;i++)
+ if (!s[i])
+ memset(dp+i,0,sizeof *dp);
+
+ write_block(fd,WHERE(0,d1),mbr);
+
+ close(fd);
return 0;
}
diff --git a/release/libdisk/Makefile b/release/libdisk/Makefile
index 4128a2966cf8..18d1cbae34cd 100644
--- a/release/libdisk/Makefile
+++ b/release/libdisk/Makefile
@@ -1,14 +1,32 @@
.PATH: /usr/src/sbin/disklabel
OBJS= tst01.o blocks.o disklabel.o dkcksum.o chunk.o disk.o change.o \
- create_chunk.o rules.o write_disk.o
+ create_chunk.o rules.o write_disk.o data.o
CFLAGS+= -Wall -g
test: tst01
cp tst01 /0
./tst01 wd1
+fd: tst01
+ -umount /dev/fd1
+ -umount /mnt
+ mount /dev/fd1 /mnt
+ strip tst01
+ gzip < tst01 > /mnt/stand/disklayout
+ chmod 755 /mnt/stand/disklayout
+ -umount /mnt
+
+BOOTS=/usr/mdec
+data.o:
+ file2c 'const unsigned char boot1[] = {' '};' \
+ < ${BOOTS}/boot1 > tmp.c
+ file2c 'const unsigned char boot2[] = {' '};' \
+ < ${BOOTS}/boot2 >> tmp.c
+ cc ${CFLAGS} -o data.o -c tmp.c
+
tst01: ${OBJS}
- cc ${CFLAGS} -static -o tst01 ${OBJS} -lreadline -ltermcap
+ #cc ${CFLAGS} -DREADLINE -static -o tst01 ${OBJS} -lreadline -ltermcap
+ cc ${CFLAGS} -static -o tst01 ${OBJS}
clean:
rm -f *.o *.core tst01
diff --git a/release/libdisk/blocks.c b/release/libdisk/blocks.c
index 65d0dae72e5d..85a9c44cf707 100644
--- a/release/libdisk/blocks.c
+++ b/release/libdisk/blocks.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id$
+ * $Id: blocks.c,v 1.2 1995/04/29 01:55:17 phk Exp $
*
*/
@@ -31,3 +31,11 @@ read_block(int fd, daddr_t block)
return foo;
}
+void
+write_block(int fd, daddr_t block, void *foo)
+{
+ if (-1 == lseek(fd,block * 512,SEEK_SET))
+ err(1,"lseek");
+ if (512 != write(fd,foo, 512))
+ err(1,"write");
+}
diff --git a/release/libdisk/chunk.c b/release/libdisk/chunk.c
index e81c646ae3b3..9b3a6bd46cf2 100644
--- a/release/libdisk/chunk.c
+++ b/release/libdisk/chunk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: chunk.c,v 1.2 1995/04/29 01:55:19 phk Exp $
+ * $Id: chunk.c,v 1.3 1995/04/29 04:00:54 phk Exp $
*
*/
@@ -190,7 +190,7 @@ Add_Chunk(struct disk *d, u_long offset, u_long size, char *name, chunk_e type,
c2->size = c1->size = size;
c2->end = c1->end = end;
c1->name = strdup(name);
- c2->name = strdup(name);
+ c2->name = strdup("-");
c1->type = type;
c2->type = unused;
c1->flags = flags;
@@ -302,6 +302,7 @@ Delete_Chunk(struct disk *d, struct chunk *c)
Free_Chunk(c3);
goto scan;
}
+ Fixup_Names(d);
return 0;
}
diff --git a/release/libdisk/create_chunk.c b/release/libdisk/create_chunk.c
index 82c0082d82c2..27652e645f65 100644
--- a/release/libdisk/create_chunk.c
+++ b/release/libdisk/create_chunk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: create_chunk.c,v 1.2 1995/04/29 01:55:20 phk Exp $
+ * $Id: create_chunk.c,v 1.3 1995/04/29 07:21:10 phk Exp $
*
*/
@@ -24,15 +24,16 @@
void
Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
{
- struct chunk *c1, *c2, *c3;
+ struct chunk *c1, *c3;
int j;
char *p=0;
+ if (!strcmp(c->name, "X")) return;
for (c1 = c->part; c1 ; c1 = c1->next) {
if (c1->type == unused) continue;
if (c1->type == reserved) continue;
if (strcmp(c1->name, "X")) continue;
- for(j=0;j<=8;j++) {
+ for(j=0;j<8;j++) {
if (j == 2)
continue;
p = malloc(12);
@@ -56,7 +57,7 @@ Fixup_FreeBSD_Names(struct disk *d, struct chunk *c)
void
Fixup_Extended_Names(struct disk *d, struct chunk *c)
{
- struct chunk *c1, *c2, *c3;
+ struct chunk *c1, *c3;
int j;
char *p=0;
@@ -127,6 +128,8 @@ int
Create_Chunk(struct disk *d, u_long offset, u_long size, chunk_e type, int subtype, u_long flags)
{
int i;
+ u_long l1,l2,end = offset + size;
+
i = Add_Chunk(d,offset,size,"X",type,subtype,flags);
Fixup_Names(d);
return i;
diff --git a/release/libdisk/disk.c b/release/libdisk/disk.c
index 24d2657036aa..fb483e0aedbb 100644
--- a/release/libdisk/disk.c
+++ b/release/libdisk/disk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: disk.c,v 1.4 1995/04/29 04:50:37 phk Exp $
+ * $Id: disk.c,v 1.5 1995/04/29 07:21:11 phk Exp $
*
*/
@@ -40,21 +40,24 @@ Int_Open_Disk(char *name, u_long size)
struct disklabel dl;
char device[64];
struct disk *d;
+ struct dos_partition *dp;
+ void *p;
strcpy(device,"/dev/r");
strcat(device,name);
+ d = (struct disk *)malloc(sizeof *d);
+ if(!d) err(1,"malloc failed");
+ memset(d,0,sizeof *d);
+
fd = open(device,O_RDONLY);
if (fd < 0) {
warn("open(%s) failed",device);
return 0;
}
- i = ioctl(fd,DIOCGDINFO,&dl);
- if (i < 0) {
- warn("DIOCGDINFO(%s) failed",device);
- close(fd);
- return 0;
- }
+
+ memset(&dl,0,sizeof dl);
+ ioctl(fd,DIOCGDINFO,&dl);
i = ioctl(fd,DIOCGSLICEINFO,&ds);
if (i < 0) {
warn("DIOCGSLICEINFO(%s) failed",device);
@@ -62,18 +65,27 @@ Int_Open_Disk(char *name, u_long size)
return 0;
}
- d = (struct disk *)malloc(sizeof *d);
- if(!d) err(1,"malloc failed");
+ if (!size)
+ size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
- memset(d,0,sizeof *d);
+ p = read_block(fd,0);
+ dp = (struct dos_partition*)(p+DOSPARTOFF);
+ for(i=0;i<NDOSPART;i++) {
+ if (dp->dp_start >= size) continue;
+ if (dp->dp_start+dp->dp_size >= size) continue;
+ if (!dp->dp_size) continue;
+
+ if (dp->dp_typ == DOSPTYP_ONTRACK)
+ d->flags |= DISK_ON_TRACK;
+
+ }
+ free(p);
d->bios_sect = dl.d_nsectors;
d->bios_hd = dl.d_ntracks;
d->name = strdup(name);
- if (!size)
- size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
if (dl.d_ntracks && dl.d_nsectors)
d->bios_cyl = size/(dl.d_ntracks*dl.d_nsectors);
@@ -85,7 +97,7 @@ Int_Open_Disk(char *name, u_long size)
if (Add_Chunk(d, 0, 1, "-",reserved,0,0))
warn("Failed to add MBR chunk");
- for(i=BASE_SLICE;i<ds.dss_nslices;i++) {
+ for(i=BASE_SLICE;i < 12 && i<ds.dss_nslices;i++) {
char sname[20];
chunk_e ce;
u_long flags=0;
@@ -132,18 +144,21 @@ Int_Open_Disk(char *name, u_long size)
if (!dl->d_partitions[j].p_size)
continue;
if (Add_Chunk(d,
- dl->d_partitions[j].p_offset,
+ dl->d_partitions[j].p_offset +
+ ds.dss_slices[i].ds_offset,
dl->d_partitions[j].p_size,
pname,part,0,0))
- warn("Failed to add chunk for partition %c",j + 'a');
+ warn(
+ "Failed to add chunk for partition %c [%lu,%lu]",
+ j + 'a',dl->d_partitions[j].p_offset,dl->d_partitions[j].p_size);
}
sprintf(pname,"%sd",sname);
- if (!dl->d_partitions[3].p_size)
- continue;
- Add_Chunk(d,
- dl->d_partitions[3].p_offset,
- dl->d_partitions[3].p_size,
- pname,part,0,0);
+ if (dl->d_partitions[3].p_size)
+ Add_Chunk(d,
+ dl->d_partitions[3].p_offset +
+ ds.dss_slices[i].ds_offset,
+ dl->d_partitions[3].p_size,
+ pname,part,0,0);
}
free(dl);
}
@@ -159,6 +174,8 @@ Debug_Disk(struct disk *d)
printf(" flags=%lx",d->flags);
printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
printf(" bios_geom=%lu/%lu/%lu\n",d->bios_cyl,d->bios_hd,d->bios_sect);
+ printf(" boot1=%p, boot2=%p, bootmgr=%p\n",
+ d->boot1,d->boot2,d->bootmgr);
Debug_Chunk(d->chunks);
}
diff --git a/release/libdisk/libdisk.h b/release/libdisk/libdisk.h
index a84481450eb0..827fd4bfbba1 100644
--- a/release/libdisk/libdisk.h
+++ b/release/libdisk/libdisk.h
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: libdisk.h,v 1.4 1995/04/29 04:50:38 phk Exp $
+ * $Id: libdisk.h,v 1.5 1995/04/29 07:21:11 phk Exp $
*
*/
@@ -22,7 +22,6 @@ struct disk {
char *name;
u_long flags;
# define DISK_ON_TRACK 1
-# define DISK_REAL_GEOM 2
u_long real_cyl;
u_long real_hd;
u_long real_sect;
@@ -44,9 +43,6 @@ struct chunk {
char *name;
chunk_e type;
int subtype;
-# define SUBTYPE_BSD_FS 1
-# define SUBTYPE_BSD_SWAP 2
-# define SUBTYPE_BSD_UNUSED 3
u_long flags;
# define CHUNK_PAST_1024 1
/* this chunk cannot be booted from */
@@ -142,6 +138,40 @@ Write_Disk(struct disk *d);
/* Write all the MBRs, disklabels, bootblocks and boot managers
*/
+int
+Cyl_Aligned(struct disk *d, u_long offset);
+ /* Check if offset is aligned on a cylinder according to the
+ * bios geometry
+ */
+
+u_long
+Next_Cyl_Aligned(struct disk *d, u_long offset);
+ /* Round offset up to next cylinder according to the bios-geometry
+ */
+
+u_long
+Prev_Cyl_Aligned(struct disk *d, u_long offset);
+ /* Round offset down to previous cylinder according to the bios-
+ * geometry
+ */
+
+int
+Track_Aligned(struct disk *d, u_long offset);
+ /* Check if offset is aligned on a track according to the
+ * bios geometry
+ */
+
+u_long
+Next_Track_Aligned(struct disk *d, u_long offset);
+ /* Round offset up to next track according to the bios-geometry
+ */
+
+u_long
+Prev_Track_Aligned(struct disk *d, u_long offset);
+ /* Check if offset is aligned on a track according to the
+ * bios geometry
+ */
+
/*
* Implementation details >>> DO NOT USE <<<
*/
@@ -152,11 +182,9 @@ struct chunk * Clone_Chunk(struct chunk *);
int Add_Chunk(struct disk *, u_long , u_long , char *, chunk_e, int , u_long);
void Bios_Limit_Chunk(struct chunk *, u_long);
void * read_block(int, daddr_t );
+void write_block(int fd, daddr_t block, void *foo);
struct disklabel * read_disklabel(int, daddr_t);
u_short dkcksum(struct disklabel *);
-int Aligned(struct disk *d, u_long offset);
-u_long Next_Aligned(struct disk *d, u_long offset);
-u_long Prev_Aligned(struct disk *d, u_long offset);
struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e);
struct disk * Int_Open_Disk(char *name, u_long size);
@@ -181,6 +209,8 @@ struct disk * Int_Open_Disk(char *name, u_long size);
* Make Create_DWIM().
*
* Make Is_Unchanged(struct disk *d1, struct chunk *c1)
+ *
+ * Make Set_Active_Slice()
*
*Sample output from tst01:
*
diff --git a/release/libdisk/rules.c b/release/libdisk/rules.c
index 9a53b4ef3bd2..ef50415e15ba 100644
--- a/release/libdisk/rules.c
+++ b/release/libdisk/rules.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: rules.c,v 1.2 1995/04/29 04:00:56 phk Exp $
+ * $Id: rules.c,v 1.3 1995/04/29 07:21:12 phk Exp $
*
*/
@@ -21,7 +21,7 @@
#include "libdisk.h"
int
-Aligned(struct disk *d, u_long offset)
+Track_Aligned(struct disk *d, u_long offset)
{
if (!d->bios_sect)
return 1;
@@ -31,7 +31,7 @@ Aligned(struct disk *d, u_long offset)
}
u_long
-Prev_Aligned(struct disk *d, u_long offset)
+Prev_Track_Aligned(struct disk *d, u_long offset)
{
if (!d->bios_sect)
return offset;
@@ -39,11 +39,37 @@ Prev_Aligned(struct disk *d, u_long offset)
}
u_long
-Next_Aligned(struct disk *d, u_long offset)
+Next_Track_Aligned(struct disk *d, u_long offset)
{
if (!d->bios_sect)
return offset;
- return Prev_Aligned(d,offset + d->bios_sect);
+ return Prev_Track_Aligned(d,offset + d->bios_sect);
+}
+
+int
+Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return 1;
+ if (offset % (d->bios_sect * d->bios_hd))
+ return 0;
+ return 1;
+}
+
+u_long
+Prev_Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return offset;
+ return (offset / (d->bios_sect*d->bios_hd)) * d->bios_sect * d->bios_hd;
+}
+
+u_long
+Next_Cyl_Aligned(struct disk *d, u_long offset)
+{
+ if (!d->bios_sect || !d->bios_hd)
+ return offset;
+ return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd));
}
/*
@@ -58,9 +84,13 @@ Rule_000(struct disk *d, struct chunk *c, char *msg)
if (c->type != whole)
return;
- for (i=0, c1=c->part; c1; c1=c1->next)
- if (c1->type != unused)
- i++;
+ for (i=0, c1=c->part; c1; c1=c1->next) {
+ if (c1->type != reserved)
+ continue;
+ if (c1->type != reserved)
+ continue;
+ i++;
+ }
if (i <= NDOSPART)
return;
sprintf(msg+strlen(msg),
@@ -86,13 +116,13 @@ Rule_001(struct disk *d, struct chunk *c, char *msg)
continue;
if (c1->type == unused)
continue;
- if (!Aligned(d,c1->offset))
+ if (!Track_Aligned(d,c1->offset))
sprintf(msg+strlen(msg),
"chunk '%s' [%ld..%ld] does not start on a track boundary\n",
c1->name,c1->offset,c1->end);
- if (c->end != c1->end && !Aligned(d,c1->end+1))
+ if (c->end != c1->end && !Cyl_Aligned(d,c1->end+1))
sprintf(msg+strlen(msg),
- "chunk '%s' [%ld..%ld] does not end on a track boundary\n",
+ "chunk '%s' [%ld..%ld] does not end on a cylinder boundary\n",
c1->name,c1->offset,c1->end);
}
}
@@ -143,6 +173,29 @@ Rule_003(struct disk *d, struct chunk *c, char *msg)
}
}
+/*
+ * Rule#4:
+ * Max seven 'part' as children of 'freebsd'
+ */
+void
+Rule_004(struct disk *d, struct chunk *c, char *msg)
+{
+ int i;
+ struct chunk *c1;
+
+ if (c->type != freebsd)
+ return;
+ for (i=0, c1=c->part; c1; c1=c1->next) {
+ if (c1->type != part)
+ continue;
+ i++;
+ }
+ if (i > 7) {
+ sprintf(msg+strlen(msg),
+ "Max seven 'part' allowed as child of 'freebsd'\n");
+ }
+}
+
void
Check_Chunk(struct disk *d, struct chunk *c, char *msg)
{
@@ -150,6 +203,7 @@ Check_Chunk(struct disk *d, struct chunk *c, char *msg)
Rule_001(d,c,msg);
Rule_002(d,c,msg);
Rule_003(d,c,msg);
+ Rule_004(d,c,msg);
if (c->part)
Check_Chunk(d,c->part,msg);
if (c->next)
diff --git a/release/libdisk/tst01.c b/release/libdisk/tst01.c
index 4a866ba4d4b7..e175b5c59876 100644
--- a/release/libdisk/tst01.c
+++ b/release/libdisk/tst01.c
@@ -6,16 +6,19 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: tst01.c,v 1.4 1995/04/29 04:50:39 phk Exp $
+ * $Id: tst01.c,v 1.5 1995/04/29 07:21:13 phk Exp $
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
#include <err.h>
+#ifdef READLINE
#include <readline/readline.h>
#include <readline/history.h>
+#endif
#include <sys/types.h>
#include "libdisk.h"
@@ -26,6 +29,9 @@ main(int argc, char **argv)
{
struct disk *d,*db;
char myprompt[BUFSIZ];
+#ifndef READLINE
+ char input[BUFSIZ];
+#endif
char *p,*q=0;
char **cp,*cmds[200];
int ncmd,i;
@@ -36,7 +42,7 @@ main(int argc, char **argv)
}
d = Open_Disk(argv[1]);
if (!d)
- err(1,"Coudn't open disk %s",argv[1]);
+ err(1,"Couldn't open disk %s",argv[1]);
sprintf(myprompt,"%s %s> ",argv[0],argv[1]);
while(1) {
@@ -47,12 +53,18 @@ main(int argc, char **argv)
printf("%s",p);
free(p);
}
+#ifdef READLINE
if (q)
free(q);
q = p = readline(myprompt);
+#else
+ printf(myprompt);
+ fflush(stdout);
+ q = p = fgets(input,sizeof(input),stdin);
+#endif
if(!p)
break;
- for(cp = cmds; (*cp = strsep(&p, " \t")) != NULL;)
+ for(cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
if (**cp != '\0')
cp++;
ncmd = cp - cmds;
@@ -128,9 +140,16 @@ main(int argc, char **argv)
d = db;
continue;
}
+ if (!strcasecmp(*cmds,"boot")) {
+ extern u_char boot1[],boot2[];
+ Set_Boot_Blocks(d,boot1,boot2);
+ continue;
+ }
if (!strcasecmp(*cmds,"write")) {
printf("Write=%d\n",
Write_Disk(d));
+ Free_Disk(d);
+ d = Open_Disk(d->name);
continue;
}
if (strcasecmp(*cmds,"help"))
@@ -138,6 +157,7 @@ main(int argc, char **argv)
printf("CMDS:\n");
printf("\tallfreebsd\n");
printf("\tbios cyl hd sect\n");
+ printf("\tboot\n");
printf("\tcollapse [pointer]\n");
printf("\tcreate offset size enum subtype flags\n");
printf("\tdelete pointer\n");
diff --git a/release/libdisk/write_disk.c b/release/libdisk/write_disk.c
index aa7190503a0b..f39c67df8154 100644
--- a/release/libdisk/write_disk.c
+++ b/release/libdisk/write_disk.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id$
+ * $Id: write_disk.c,v 1.1 1995/04/29 07:21:14 phk Exp $
*
*/
@@ -25,10 +25,166 @@
#define DOSPTYP_EXTENDED 5
#define DOSPTYP_ONTRACK 84
+#define BBSIZE 8192
+
+#define WHERE(offset,disk) (disk->flags & DISK_ON_TRACK ? offset + 63 : offset)
+int
+Write_FreeBSD(int fd, struct disk *new, struct disk *old, struct chunk *c1)
+{
+ struct disklabel *dl;
+ struct chunk *c2;
+ int i,j;
+ void *p;
+ u_char buf[BBSIZE];
+
+ for(i=0;i<BBSIZE/512;i++) {
+ p = read_block(fd,i + c1->offset);
+ memcpy(buf+512*i,p,512);
+ free(p);
+ }
+ if(new->boot1)
+ memcpy(buf,new->boot1,512);
+
+ if(new->boot2)
+ memcpy(buf+512,new->boot2,BBSIZE-512);
+
+ dl = (struct disklabel *) (buf+512*LABELSECTOR+LABELOFFSET);
+ memset(dl,0,sizeof *dl);
+
+ printf("--> Write_FreeBSD()\n");
+
+ for(c2=c1->part;c2;c2=c2->next) {
+ if (c2->type == unused) continue;
+ if (c2->type == reserved) continue;
+ if (!strcmp(c2->name,"X")) continue;
+ j = c2->name[5] - 'a';
+ if (j < 0 || j >= MAXPARTITIONS || j == RAW_PART) {
+ warn("Weird parititon letter %c",c2->name[5]);
+ continue;
+ }
+ dl->d_partitions[j].p_size = c2->size;
+ dl->d_partitions[j].p_offset = c2->offset - c1->offset;
+
+ }
+
+ dl->d_bbsize = BBSIZE;
+
+ strcpy(dl->d_typename,c1->name);
+
+ dl->d_secperunit = new->chunks->size;
+ dl->d_secpercyl = new->real_cyl ? new->real_cyl : new->bios_cyl;
+ dl->d_ntracks = new->real_hd ? new->real_hd : new->bios_hd;
+ dl->d_nsectors = new->real_sect ? new->real_sect : new->bios_sect;
+
+ dl->d_npartitions = MAXPARTITIONS;
+
+ dl->d_type = new->name[0] == 's' ? DTYPE_SCSI : DTYPE_ESDI;
+ dl->d_partitions[RAW_PART].p_size = c1->size;
+ dl->d_partitions[RAW_PART].p_offset = 0;
+
+ dl->d_magic = DISKMAGIC;
+ dl->d_magic2 = DISKMAGIC;
+ dl->d_checksum = dkcksum(dl);
+
+ for(i=0;i<BBSIZE/512;i++) {
+ write_block(fd,WHERE(i + c1->offset,new),buf+512*i);
+ }
+
+ return 0;
+}
+
+int
+Write_Extended(int fd, struct disk *new, struct disk *old, struct chunk *c1)
+{
+ printf("--> Write_Extended()\n");
+ Print_Chunk(c1);
+ return 0;
+}
int
Write_Disk(struct disk *d1)
{
+ int fd,i,j;
+ struct disk *old = 0;
+ struct chunk *c1;
+ int ret = 0;
+ char device[64];
+ void *mbr;
+ struct dos_partition *dp;
+ int s[4];
+
+ strcpy(device,"/dev/r");
+ strcat(device,d1->name);
+
+ fd = open(device,O_RDWR);
+ if (fd < 0) {
+ warn("open(%s) failed",device);
+ return 1;
+ }
+
+ memset(s,0,sizeof s);
+ mbr = read_block(fd,0);
+ dp = (struct dos_partition*) (mbr + DOSPARTOFF);
+ for (c1=d1->chunks->part; c1 ; c1 = c1->next) {
+ if (c1->type == unused) continue;
+ if (c1->type == reserved) continue;
+ if (!strcmp(c1->name,"X")) continue;
+ if (c1->type == extended)
+ ret += Write_Extended(fd, d1,old,c1);
+ if (c1->type == freebsd)
+ ret += Write_FreeBSD(fd, d1,old,c1);
+ j = c1->name[4] - '1';
+ if (j < 0 || j > 3)
+ continue;
+ s[j]++;
+ dp[j].dp_start = c1->offset;
+ dp[j].dp_size = c1->size;
+
+ i = c1->offset;
+ if (i >= 1024*d1->bios_sect*d1->bios_hd)
+ i = 1024*d1->bios_sect*d1->bios_hd - 1;
+ dp[j].dp_ssect = i % d1->bios_sect;
+ i -= dp[j].dp_ssect;
+ i /= d1->bios_sect;
+ dp[j].dp_ssect++;
+ dp[j].dp_shd = i % d1->bios_hd;
+ i -= dp[j].dp_shd;
+ i /= d1->bios_hd;
+ dp[j].dp_scyl = i;
+
+ i = c1->end;
+ if (i >= 1024*d1->bios_sect*d1->bios_hd)
+ i = 1024*d1->bios_sect*d1->bios_hd - 1;
+ dp[j].dp_esect = i % d1->bios_sect;
+ i -= dp[j].dp_esect;
+ i /= d1->bios_sect;
+ dp[j].dp_esect++;
+ dp[j].dp_ehd = i % d1->bios_hd;
+ i -= dp[j].dp_ehd;
+ i /= d1->bios_hd;
+ dp[j].dp_ecyl = i;
+ switch (c1->type) {
+ case freebsd:
+ dp[j].dp_typ = 0xa5;
+ break;
+ case fat:
+ dp[j].dp_typ = 1;
+ break;
+ case extended:
+ dp[j].dp_typ = 5;
+ break;
+ case foo:
+ dp[j].dp_typ = - c1->subtype;
+ break;
+ }
+ }
+ for(i=0;i<NDOSPART;i++)
+ if (!s[i])
+ memset(dp+i,0,sizeof *dp);
+
+ write_block(fd,WHERE(0,d1),mbr);
+
+ close(fd);
return 0;
}