Leisner.Henr@xerox.com (marty) (05/20/88)
I'm currently trying to do a rewrite of dos[dir/read/write] to handle hard disks. The first thing I did was have the argument specify the block special device (/dev/fd0 instead of 0). However, it seems hard disks are a major pain. In order to compute the fat size, there is this mega-equation in the DOS tech reference manual, based on some generic system parameters and the number of sectors in the partition. So I need a way to determine sectors/partition. The algorithm would have to look something like: if(floppy disk) if(360K floppy) do 360k floppy if(1.2 meg floppy) do 1.2 meg floppy else /* hard disk */ figure out sectors for this partitions (somehow) check first fat entry for hard disk partition ID do good stuff end I suppose the major device numbers could be examined to determine floppy/hard disks. But in multiple hard disk systems, how would the boot block be read in? Or is there a better way to determine number sectors/drive? Seek off the end? Then divide the offset by SECTOR_SIZE? marty ARPA: leisner.henr@xerox.com GV: leisner.henr NS: martin leisner:henr801c:xerox UUCP: nsc!nscimg!amps!marty
rtregn@faui44.informatik.uni-erlangen.de (Robert Regn ) (05/31/88)
I've already tried to modify DOSxxx to handle hard disk's. It uses the boot sector. I made a link of /dev/hd<n> to /dev/at2, so I need not remember which partition is dos. The program - diff to 1.2 is included - works (for 12 bit fats) ok as dosdir and dosread, but as doswrite it destroys my dos partition (e.g. root dir)! Make a 100KB backup of the dos partition with dd if you try doswrite. I've put debug messages in "disk_io", but the behavior seems ok. If i use doswrite on a file which contains a copy of the dos partitions first MB, the program works! (Is the problem caused by the driver ??) Can somebody send me the "mega-equation" referenced by Marty ? Can somebody say what hiddensec means ? ------------------------------ diff to dosread.c 1.2 --------------- 20a21 > #define HARDDISK 0xF8 22,24c23,25 < #define MAX_CLUSTER_SIZE 1024 < #define MAX_FAT_SIZE 3584 /* 7 sectoren */ < #define MAX_ROOT_ENTRIES 224 /* 14 sectoren */ --- > #define MAX_CLUSTER_SIZE 4096 > #define MAX_FAT_SIZE 6144 > #define MAX_ROOT_ENTRIES 512 89c90 < short total_clusters, cluster_size, fat_size, --- > unsigned short total_clusters, cluster_size, fat_size, 114a116,141 > determine() > { > struct dosboot { > short jump; > char nop; > char name[8]; > char byteps_1; /* short wuerde um 1byte hochgeschoben */ > char byteps_2; > char secpclus; > short reservsec; > char fats; > char rooten_1; /* Alignment */ > char rooten_2; > char totsec_1; > char totsec_2; > char media; > short secpfat; > short secptrack; > short heads; > short hiddensec; > /* char fill[482]; */ > } boot; > unsigned int bytepers, dirents, totsec; > char stderr[100]; > /* read Bios-Parameterblock */ > disk_read(0L, &boot, sizeof boot); 115a143,190 > bytepers = ((int) boot.byteps_2) <<8 + boot.byteps_1; > dirents = ((int) boot.rooten_2) <<8 + boot.rooten_1; > /*totsec = ((int) boot.totsec_2) <<8 + boot.totsec_1;*/ > totsec = boot.totsec_2 <<8; > totsec += boot.totsec_1; > > total_clusters = totsec/boot.secpclus; > cluster_size = bytepers * boot.secpclus; > fat_size = boot.secpfat * bytepers; > data_start = bytepers + boot.fats* fat_size + dirents * 32; > root_entries = dirents; > sub_entries = boot.secpclus * bytepers/32; > > #ifdef debug > sprintf(stderr, "fatsize: %u totclusters: %u totsec %u ( %x %x)\n", > fat_size,total_clusters, totsec, boot.totsec_2, boot.totsec_1); > write(2,stderr, strlen(stderr)); > sprintf(stderr, "dirents %u bytepers %u\n", dirents, bytepers); > write(2,stderr, strlen(stderr)); > #endif > > /* safety checking */ > if ( boot.fats != 2 && dos_write) > {print_string (TRUE, "fats != 2 - Can't handle disk\n"); > leave (2); > } > if ( boot.reservsec != 1) > {print_string (TRUE, "reserved != 1 - Can't handle disk\n"); > leave (2); > } > if ( total_clusters > 4096) > {print_string (TRUE, "no 12 Bit fat - Can't handle disk\n"); > leave (2); > } > if (fat_size > MAX_FAT_SIZE) > {print_string (TRUE, "fatsize to big - Can't handle disk\n"); > leave (2); > } > if (cluster_size > MAX_CLUSTER_SIZE) > {print_string (TRUE, "clustersize to big - Can't handle disk\n"); > leave (2); > } > if ( boot.media &0xFF != HARDDISK) > {printf("improper media descriptor: %x\n", boot.media); > leave (2); > } > } > 184a260,261 > else if (fat[0] == HARDDISK) /*Hard Disk*/ > determine(); 199c276 < if (dos_dir) { --- > if (dos_dir && Lflag) { 211c288,289 < print(STD_OUT, "Root directory:\n", 0); --- > if (Lflag) > print(STD_OUT, "Root directory:\n", 0); 213c291,292 < free_blocks(); --- > if (Lflag) > free_blocks(); 229c308 < if (dos_dir) --- > if (dos_dir && Lflag) 236c315,316 < free_blocks(); --- > if (Lflag) > free_blocks(); ------------------------------ end diff to dosread.c 1.2 --------------- Robert Regn
mmdf@udel.UUCP (06/03/88)
There is a major bug/design flaw in the Minix winchester driver which is a problem for reading the boot partition. In kernel/wini/copy_prt, disk partitions are rounded up to a block boundary and the size is rounded down to a block boundary. So if the first sector of a dos partition is odd, you can't read the boot record. Strange..... I'm using the following code now: #define PART_TABLE 0x1be /* where partitoin table actually starts */ /* borrowed from block0.h of fdisk */ typedef struct { unsigned char blk0_boot; /* boot partition */ unsigned char blk0_s_h; /* starting head */ unsigned char blk0_s_s; /* starting sector */ unsigned char blk0_s_c; /* starting cylinder */ unsigned char blk0_sys; /* partition type */ unsigned char blk0_e_h; /* ending head */ unsigned char blk0_e_s; /* ending sector */ unsigned char blk0_e_c; /* ending cylinder */ long blk0_start; /* starting sector */ long blk0_size; /* size in sectors */ } PARTITION_INFO; PRIVATE copy_prt(drive) int drive; { PARTITION_INFO *part_info; struct wini *wn; int part_num; for(part_num = 0, wn = &wini[drive + 1], part_info = (PARTITION_INFO *) &buf[PART_TABLE]; part_num < 4; part_num++, wn++, part_info++ ) { wn->wn_low = part_info->blk0_start; wn->wn_size = part_info->blk0_size; if(wn->wn_size % SECTORS_PER_BLOCK) /* round down to even number of blocks */ wn->wn_size = (wn->wn_size/SECTORS_PER_BLOCK - 1)*SECTORS_PER_BLOCK; } } Only problem is if you previously built a Minix partition on an odd sector boundary -- you can't read it anymore. The mega-equation is taken care of in the boot record -- DOS has an elaborate equation to figure out the number of fat sectors when the format is done. marty ARPA: leisner.henr@xerox.com GV: leisner.henr NS: martin leisner:henr801c:xerox UUCP: nsc!nscimg!amps!marty