The Third PC Utility: cpsw.exeOur last of three programs is of use when the early BSD operating system kernel is running and must receive additional files. Ordinarily, we would prefer to use either serial communications or floppy disks to add files to our nascent BSD root filesystem. However, our early kernel has drivers for only the display, keyboard, and hard disk drive (that is, the "bare minimum"), because we want to use the system itself to develop and test further extensions and improvements. In a nutshell, we want to leverage our tiny BSD UNIX system with MS-DOS's drivers and applications programs by using MS-DOS to receive information into a MS-DOS file, and then using a trivial program to place this information on a reserved portion of the disk, where BSD can easily access it. Listing 7: Copy to Swap area Program (file: cpsw.c)
/* Copyright (c) 1989, 1990 William Jolitz. All rights reserved.
* Written by William Jolitz 7/89
* Redistribution and use in source and binary forms are freely permitted
* provided that the above copyright notice and attribution and date of work
* and this paragraph are duplicated in all such forms.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* This program copies a MSDOS file to BSD's idea of a swap partition,
* known to be the second one in the disklabel. Typical use is to place
* a TAR formatted file, obtained from a cross-host, onto swap. Then
* BSD is booted with the boot program and the BSD tar utility is
* used to extract the files being transferred within the TAR image,
* hopefully before we need to page on the swap space. Again, this
* program is rude in requiring one to adjust the manifest constant
* denoting the cylinder on which the BSD root filesystem appears,
* but this is another throw-away program to get the real work started.
* Currently works with TURBO C 1.5 .
*/
#include <bios.h>
#include <alloc.h>
#include <fcntl.h>
#include <sys\stat.h>
#include "diskl.h"
/* Location of root partition. Adjust to suit given drive partition layout. */
#define OFF_CYL 290 /* Cylinder offset of start of BSD root partition */
char *trkbuf;
#define BSIZE 512
struct label_blk {
char bufr[LABELOFFSET];
struct disklabel dl;
} lbl;
main(argc, argv) char *argv[]; {
int fi, rem, cyl, head, tfrcnt;
int bsize, ncyl, ntrack, nsect, off_cyl, maxcyl;
if (argc != 2) {
printf("usage: cpsw <file>\n");
exit(1);
}
fi = open(argv[1], O_BINARY);
if (fi < 0) {
printf("Cannot open \"%s\" file to BSD swap\n",
argv[1]);
exit(1);
}
/* check for presence of disklabel */
biosdisk(2, 0x80, 0, OFF_CYL, LABELSECTOR, 1, &lbl);
if (lbl.dl.dk_magic != 0xabc) {
printf("BSD root disk partition does not have a label!\n");
exit(1);
}
/* Extract disk geometry and swap partition location from disk label. */
bsize = lbl.dl.dk_secsize;
nsect = lbl.dl.dk_nsectors;
ntrack = lbl.dl.dk_ntracks;
off_cyl = lbl.dl.dk_partition[1].cyloff;
maxcyl = lbl.dl.dk_partition[1].cyloff +
lbl.dl.dk_partition[1].nblocks / lbl.dl.dk_secpercyl;
/* Allocate track buffer */
trkbuf = malloc (nsect*bsize);
printf("WARNING! About to overwrite disk (will loose previous\n");
printf("contents). Are you certain of your use of this program?");
if (getche() != 'y') exit(1);
printf("\n");
tfrcnt = head = 0;
cyl = off_cyl;
/* Transfer file to absolute disk section, a track at a time,
because we're impatient. */
while ((rem = read(fi, trkbuf, nsect*bsize)) == nsect*bsize) {
biosdisk(3, 0x80, head, cyl, 1, nsect, trkbuf);
if (++head == ntrack) {
head = 0;
if (++cyl > maxcyl) {
printf("Overran swap partition!\n");
exit(1);
}
}
tfrcnt += nsect;
printf("Amount transferred %5dK bytes\r",
tfrcnt*BSIZE/1024);
}
/* Transfer any remainder leftover */
if (rem > BSIZE-1) {
biosdisk(3, 0x80, head, cyl, 1, rem/bsize, trkbuf);
tfrcnt += rem/bsize;
printf("Amount transferred %5dK bytes\n",
tfrcnt*bsize/1024);
}
exit(0);
}
At this point, we had seriously considered giving BSD the ability to read MS-DOS file structures directly, but this is a nontrivial process and we wished to devote our energies toward developing and improving the BSD kernel to become self-supporting. As a consequence, we decided to push this project off and favor instead an expedient solution to a temporary problem. If more disk space had been available, a partition could have been dedicated to the MS-DOS communications functions. Unfortunately, our early host machine contained only a 40-Mbyte drive, so we were very tight on space. (Yes, I know we have large machines now, but when you begin a project, it is usually on the cheap until you convince people that it is worthwhile -- of course, by that time you've probably finished the project, or at least a fair portion of it). We elected to force the swap space to do double duty, by arranging to use it to hold information from and to MS-DOS just after or before BSD system operation. We were counting on the fact that we only use the swap space when the system really gets rolling. While this arrangement is somewhat heretical, it worked adequately enough to let us finish our nascent system to the point where it no longer required MS-DOS to boot or exchange files with other systems. cpsw.c (see Listing 7) differs from cpfs.c in that it uses the disk label to configure itself. Disk geometry is determined entirely from the disk label. Prior to using cpsw.c, a TAR file image is created on a cross-host. This file is then transferred to an MS-DOS file via one of the many MS-DOS communications programs available. cpsw.exe is used to make this file accessible to 386BSD. 386BSD is then booted, and the 386BSD TAR utility is invoked to extract the information (prior to paging). This method is somewhat tedious, but proved adequate for the early stages of this port. cpsw.exe is very similar in function to cpfs.exe, and both could be subsumed into a single program. Simplicity, however, has allowed us to achieve our goal of getting 386BSD off the ground and running, without becoming an outright diversion into a MS-DOS/ UNIX merger, a weighty and significant objective not suited for an early operating system project of considerable and ever-increasing scope, but still short on history.
|
|