mkrdisk.c 3.6 KB
/*
 * Copyright (C) 1996-1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * 
 * This file is part of the SimOS distribution. 
 * See LICENSE file for terms of the license. 
 *
 */

/*
 * vh -  program to make a fake volume header for a disk file
 */
#include <stdio.h>
#include <sys/types.h>

#include <sys/immu.h>		/* for NBPP */

#include <sys/dvh.h>		/* for volume header */
#include <sys/fs/efs_sb.h>	/* for super block */

#include <sys/mman.h>		/* for mmap() */

#include <sys/stat.h>		/* for open() */
#include <sys/fcntl.h>		/* for open() */

#define HP_DISK_MODEL
#ifdef HP_DISK_MODEL
#include "../../simos/diskmodel/diskmodel.param"
#include "../../simos/diskmodel/diskdevices.h"

#define SECTOR_BYTES            SECTOR_SIZE
#define SECTORS_PER_TRACK       NSECTORS
#define TRACKS_PER_CYL          NTRACKS_PER_CYL         

#else
#define SECTOR_BYTES		512
/*
 * XXX Just picked these from the root disk on morse XXX 
 */
#define SECTORS_PER_TRACK	65
#define TRACKS_PER_CYL		15
#endif

#define MEGABYTE 1024*1024

usage(char *progname)
{
  printf("Usage: %s <file name> <file size(Mb)>\n", progname);
  return;
}

main(int argc, char **argv)
{
  register int			csum;
  int				fd;
  char				*filename;
  uint	 			filesize;
  void				*map_addr;
  register int			*p;
  register struct volume_header	*vh;
  uint				tblks;
  uint				fp;
  uint				first_cylinder;

  if (argc != 3) {
    usage(argv[0]);
    exit(1);
  }

  filename = argv[1];
  filesize = atol(argv[2])*MEGABYTE;
  fd = open(filename, O_RDWR|O_CREAT, 0644);
  if (fd == -1) {
    perror("open");
    exit(-1);
  }

  tblks = (filesize + SECTOR_BYTES -1)/SECTOR_BYTES;
  fp = lseek(fd, (tblks * SECTOR_BYTES) - 1, SEEK_SET);
  if (fp != (tblks * SECTOR_BYTES  -1)) {
     perror(argv[0]);
     exit(-1);
  }
  if (write(fd, "\000", 1) != 1) {
     perror(argv[0]);
     exit(-1);
  }	   

  map_addr = mmap(0, NBPP, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  if (map_addr == (void *)-1) {
    perror("mmap");
    exit(3);
  }

  vh = (struct volume_header *)map_addr;

  bzero(vh, sizeof(struct volume_header));

  vh->vh_magic = VHMAGIC;

  vh->vh_rootpt = 0;
  vh->vh_swappt = 1;

  vh->vh_bootfile[0] = '/';
  vh->vh_bootfile[1] = 'u';
  vh->vh_bootfile[2] = 'n';
  vh->vh_bootfile[3] = 'i';
  vh->vh_bootfile[4] = 'x';
  vh->vh_bootfile[5] = '\0';


  vh->vh_dp.dp_secbytes = SECTOR_BYTES;

  vh->vh_dp.dp_trks0 = TRACKS_PER_CYL;
  vh->vh_dp.dp_secs = SECTORS_PER_TRACK;
  vh->vh_dp.dp_spares_cyl = 0;

  vh->vh_dp.dp_cyls = (filesize + (TRACKS_PER_CYL * SECTORS_PER_TRACK * SECTOR_BYTES) - 1) /
    (TRACKS_PER_CYL * SECTORS_PER_TRACK * SECTOR_BYTES);

  /* Use the standard partition method for a sgi disk.  1 cylinder for the
     volume header, since each partition has to be cylinder aligned.
     Overlapping raw and EFS partitions.  
     1 - raw/swap 
     0 - EFS 
     8 - Volume header (1 cylinder) 
     10 - Entire volume
     */

  first_cylinder = SECTORS_PER_TRACK*TRACKS_PER_CYL;

  /* RAW */
  vh->vh_pt[1].pt_nblks = tblks - first_cylinder;
  vh->vh_pt[1].pt_firstlbn = first_cylinder;
  vh->vh_pt[1].pt_type = PTYPE_RAW;

  /* EFS */
  vh->vh_pt[0].pt_nblks = tblks - first_cylinder;
  vh->vh_pt[0].pt_firstlbn = first_cylinder;
  vh->vh_pt[0].pt_type = PTYPE_EFS;

  /* Volume header */
  vh->vh_pt[8].pt_nblks = first_cylinder;
  vh->vh_pt[8].pt_firstlbn = 0;
  vh->vh_pt[8].pt_type = PTYPE_VOLHDR;

  /* Entire volume */
  vh->vh_pt[10].pt_nblks = tblks;
  vh->vh_pt[10].pt_firstlbn = 0;
  vh->vh_pt[10].pt_type = PTYPE_VOLUME;

  csum = 0;
  for (p = (int *)vh; p < (int *)(vh + 1); p++)
    csum += *p;

  vh->vh_csum = -csum;

  close(fd);

  exit(0);
}