Now we do writes too.

This commit is contained in:
Poul-Henning Kamp 1995-04-30 06:09:29 +00:00
parent af9c31e108
commit 2d5caf92d0
18 changed files with 720 additions and 106 deletions

View File

@ -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

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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:
*

View File

@ -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)

View File

@ -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");

View File

@ -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;
}

View File

@ -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

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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:
*

View File

@ -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)

View File

@ -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");

View File

@ -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;
}