📄 usrfdiskpartlib.c
字号:
* The <nPart> argument contains the number of partitions to create. If* <nPart> is 0 or 1, then a single partition covering the entire disk is* created.* If <nPart> is between 2 and 4, then the arguments <size1>, <size2>* and <size3> contain the * .I percentage* of disk space to be assigned to the 2nd, 3rd, and 4th partitions* respectively. The first partition (partition 0) will be assigned the* remainder of space left (space hog).** Partition sizes will be round down to be multiple of whole tracks* so that partition Cylinder/Head/Track fields will be initialized * as well as the LBA fields. Although the CHS fields are written they* are not used in VxWorks, and can not be guaranteed to work correctly* on other systems.** RETURNS: OK or ERROR writing a partition table to disk**/STATUS usrFdiskPartCreate ( CBIO_DEV_ID dev, /* device representing the entire disk */ int nPart, /* how many partitions needed, default=1, max=4 */ int size1, /* space percentage for second partition */ int size2, /* space percentage for third partition */ int size3 /* space percentage for fourth partition */ ) { PART_TABLE_ENTRY partTbl[4]; int totalSecs, trackSecs, cylSecs, totalTracks, i; caddr_t secBuf = NULL ; const char dummyString[] = "Wind River Systems Inc., DosFs 2.0 Partition Table"; STATUS stat = OK; CBIO_PARAMS cbioParams; /* Get CBIO device parameters */ if (ERROR == cbioParamsGet (dev, &cbioParams)) { return (ERROR); } bzero((caddr_t) partTbl, sizeof(partTbl)); /* Verify the device handle, possibly create wrapper */ if((dev=cbioDevVerify(dev, FALSE)) == NULL) return (ERROR); /* if first time usage, a RESET may be needed on the device */ if( cbioIoctl( dev, CBIO_RESET, 0) == ERROR ) { printErr ("usrFdiskPartCreate error: device is not ready\n"); return (ERROR); } /* FDISK only works with 512 byte sectored disks, yuck ! */ if( cbioParams.cbio_bytesPerBlk != BYTES_PER_SECTOR ) { printErr ("usrFdiskPartCreate error: sector size %d " " must be 512 bytes\n", cbioParams.cbio_bytesPerBlk); errno = EINVAL; return (ERROR); } if( cbioParams.cbio_offset != 0 ) { printErr ("usrFdiskPartCreate error: disk is already partitioned\n"); errno = EINVAL; return (ERROR); } totalSecs = cbioParams.cbio_nBlocks ; trackSecs = cbioParams.cbio_blksPerTrack; if( trackSecs < 1) trackSecs = 1; cylSecs = trackSecs * cbioParams.cbio_nHeads ; if( totalSecs < trackSecs * 4 ) { printErr ("usrFdiskPartCreate error: disk too small %d blocks\n", totalSecs); errno = EINVAL; return (ERROR); } /* also, part table CHS fields have certain limitations for CHS values */ if( trackSecs < 1 || trackSecs > 63 ) { trackSecs = 64 ; cylSecs = trackSecs * cbioParams.cbio_nHeads ; } if( cylSecs < 1 ) cylSecs = trackSecs ; while((totalSecs/cylSecs) > 1023 ) cylSecs = cylSecs << 1 ; /* rest of calculation made in tracks, round, less chance of overflowing */ totalTracks = totalSecs / trackSecs ;#ifdef DEBUG printErr( " totalTracks %d, trackSecs %d, cylSecs %d\n", totalTracks, trackSecs, cylSecs );#endif /* reserve one track for MBR */ i = totalTracks = totalTracks - 1 ; switch (nPart) { case 4: partTbl[3].spare = (i * size3)/100 ; totalTracks -= partTbl[3].spare ; /*FALLTHROUGH*/ case 3: partTbl[2].spare = (i * size2)/100 ; totalTracks -= partTbl[2].spare ; /*FALLTHROUGH*/ case 2: partTbl[1].spare = (i * size1)/100 ; totalTracks -= partTbl[1].spare ; /*FALLTHROUGH*/ case 0: case 1: if( totalTracks <= 0 ) { /* partition sizes dont sum up */ /* printErr(" EINVAL: totalTracks %d\n", totalTracks ); */ errno = EINVAL; return (ERROR); } partTbl[0].spare = totalTracks ; break ; default: errno = EINVAL; return (ERROR); } /* normalize the entire partition table, calc offset etc.*/ for(i=0, totalTracks = 1; i<4; i++) { if( partTbl[i].spare == 0 ) continue ; partTbl[i].offset = totalTracks * trackSecs ; partTbl[i].nBlocks = partTbl[i].spare * trackSecs ; totalTracks += partTbl[i].spare ; /* * If the partition is greater than or equal to 2GB, * use FAT32x partition type. Else if the partition * is greater than or equal to 65536, use BIGDOS FAT * 16bit FAT, 32Bit sector number. Else if the partition * is and greater or equal to 32680 use SMALLDOS FAT, * 16bit FAT, 16bit sector num. Else use FAT12 for * anything smaller than 32680. Note: some systems * may want to change this to use the Windows95 partiton * types that support (LBA) INT 13 extensions, since the * only thing VxWorks can truely ensure is the LBA fields, * mostly since vxWorks does not use the BIOS (PC BIOS is * NOT deterministic, bad for a RTOS, plus they tend not * to be present on non-x86 targets.) and cannot ensure * the BIOS translation of CHS. Of course, the 32bit VxWorks * RTOS would never need such a hack as CHS translation. * The reason we don't use the LBA field now is that * NT 3.51 and NT 4.0 will not recognize the new partition * types (0xb-0xf). That is one reason this is shipped * in source. * * TODO: Reconsider using partition types 0xb-0xf when * MS gets their trip together. */ if(partTbl[i].nBlocks >= 0x400000) partTbl[i].flags = PART_TYPE_DOS32X; else if (partTbl[i].nBlocks >= 65536) partTbl[i].flags = PART_TYPE_DOS4; else if (partTbl[i].nBlocks >= 32680) partTbl[i].flags = PART_TYPE_DOS3; else partTbl[i].flags = PART_TYPE_DOS12; } /* allocate a local secBuf for the read sectors MBR/Part data */ if ((secBuf = malloc (BYTES_PER_SECTOR)) == NULL) { printErr ("usrFdiskPartCreate: Error allocating sector buffer.\n"); return (ERROR); } /* start filling the MBR buffer */ bzero( secBuf, BYTES_PER_SECTOR) ; /* fill the top with a silly RET sequence, not JMP */ secBuf[0] = 0x90 ; /* NOP */ secBuf[1] = 0x90 ; /* NOP */ secBuf[2] = 0xc3 ; /* RET */ bcopy( dummyString, secBuf+3, sizeof(dummyString)); /* bottom signature */ secBuf[ BYTES_PER_SECTOR-2 ] = 0x55 ; secBuf[ BYTES_PER_SECTOR-1 ] = 0xaa ; /* add our own, almost random timestamp, just before part tbl */ i = tickGet() ; /* least significant 16 bites from tick counter */ secBuf [ DOS_BOOT_PART_TBL - 4 ] = i & 0xff ; secBuf [ DOS_BOOT_PART_TBL - 3 ] = (i >> 8) & 0xff ; /* Now, fill the 4 partition entries, careful with byte ordering */ for(i = 0; i < 4; i ++ ) { FAST cyl, head, tsec, s1 ; /* calculate offset of current partition table entry */ FAST partOffset = DOS_BOOT_PART_TBL + i * 16 ; /* fill in fields */ secBuf[ partOffset + BOOT_TYPE_OFFSET] = (i) ? PART_NOT_BOOTABLE : PART_IS_BOOTABLE; secBuf[ partOffset + SYSTYPE_OFFSET] = partTbl[i].flags ; /* LBA number of sectors */ VX_TO_DISK_32( partTbl [ i ].nBlocks, &secBuf[ partOffset + NSECTORS_TOTAL]); /* LBA offset */ VX_TO_DISK_32( partTbl [ i ].offset, &secBuf[ partOffset + NSECTORS_OFFSET]); /* beginning of partition in CHS */ if( partTbl [ i ].nBlocks > 0) { s1 = partTbl [ i ].offset ; cyl = s1 / cylSecs ; head = (s1 - (cyl * cylSecs)) / trackSecs ; tsec = 1 + s1 - (cyl * cylSecs) - (head*trackSecs); } else { cyl = head = tsec = 0 ; /* unused table entry */ }#ifdef DEBUG printErr(" start cyl %d hd %d s %d\n", cyl, head, tsec );#endif secBuf[ partOffset + STARTSEC_CYL_OFFSET ] = cyl & 0xff ; secBuf[ partOffset + STARTSEC_SEC_OFFSET ] = ((cyl>>2) & 0xc0) | tsec ; secBuf[ partOffset + STARTSEC_HD_OFFSET ] = head ; /* end of partition in CHS */ if( partTbl [ i ].nBlocks > 0) { s1 = partTbl [ i ].offset + partTbl [ i ].nBlocks - 1 ; cyl = s1 / cylSecs ; head = (s1 - (cyl * cylSecs)) / trackSecs ; tsec = 1 + s1 - (cyl * cylSecs) - (head*trackSecs); } else { cyl = head = tsec = 0 ; /* unused table entry */ }#ifdef DEBUG printErr(" end cyl %d hd %d s %d\n", cyl, head, tsec );#endif secBuf[ partOffset + ENDSEC_CYL_OFFSET ] = cyl & 0xff ; secBuf[ partOffset + ENDSEC_SEC_OFFSET ] = ((cyl>>2) & 0xc0) | tsec ; secBuf[ partOffset + ENDSEC_HD_OFFSET ] = head ; } (void) cbioIoctl( dev, CBIO_DEVICE_LOCK, 0) ; /* Last but not least, write the MBR to disk */ stat = cbioBlkRW( dev, 0 , 1, secBuf, CBIO_WRITE, NULL ) ; /* flush and invalidate cache immediately */ stat |= cbioIoctl( dev, CBIO_CACHE_INVAL, 0) ; cbioRdyChgdSet (dev, TRUE) ; /* force re-mount */ (void) cbioIoctl( dev, CBIO_DEVICE_UNLOCK, 0) ; free(secBuf); return stat; }#if defined(INCLUDE_PART_SHOW)/******************************************************************************* usrFdiskPartShow - parse and display partition data** This routine is intended to be user callable.** A device dependent partition table show routine. This * routine outputs formatted data for all partition table * fields for every partition table found on a given disk,* starting with the MBR sectors partition table. This code can be * removed to reduce code size by undefining: INCLUDE_PART_SHOW* and rebuilding this library and linking to the new library.* * This routine takes three arguments. First, a CBIO pointer * (assigned for the entire physical disk) usually obtained * from dcacheDevCreate(). It also takes two block_t type * arguments and one signed int, the user shall pass zero * in these paramaters.* * For example:* .CS* sp usrFdiskPartShow (pCbio,0,0,0)* .CE** Developers may use size<arch> to view code size.* * NOTE** RETURNS: OK or ERROR** INTERNAL* This function was adopted from jkf with minimal changes*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -