📄 dospartlibata.c
字号:
/* dosPartLibAta.c - show & mount ATA HDD MSDOS partitions *//*modification history--------------------01c,15sep97,jkf removed LCHS support. Only useful for MSDOS versions before 3.3, not likely anyone needs LCHS support. Added support for big endian arches and arches without dynamic bus sizing, which involved byte swapping macro and reading sector data with macro offsets. Now supports 80x86, 68k, SPARC, MIPS, PPC, i960, etc.) Revised docs.01b,01sep97,jkf fixed check for LBA support in dosPartRdLbaAta(). fixed stdlib.h filename case for Unix. fixed args to ataDevCreate in example comments. fixed cosmetics in sector and show routines. 01a,01sep97,jkf written.*//*DESCRIPTION:This library is provided by Wind River Systems CustomerSupport strictly as an educational example.This code supports both mounting and displaying partition tables written by MSDOS FDISK.exe or by any other MSDOS FDISK.exe compatible partitioning software. The first partition table is contained within a hard drivesMaster Boot Record (MBR) sector, which is defined as sectorone, cylinder zero, head zero or logical block address zero.The mounting and displaying routines within this code will first parse the MBR partition tables entries (defined below)and also recursively parse any "extended" partition tables,which may reside within another Cylinder, Head, and Sector (CHS) combination further into the hard disk. (Also knownas extended partition tables chained from the MBR's partitiontable. MSDOS file systems within extended partitions are knownto those familiar with the MSDOS FDISK.exe utility as "Logical drives within the extended partition".Since MSDOS file systems have a fixed number of clusters, 64Kb,and clusters are the minimum allocation unit at the file systemlevel, using partitions can help optimize cluster size for a givenhard disk, improving performance and resource usage. For example, a 1-gigabyte hard disk with a single MSDOS file system has the following minimum allocation unit at the dosFsLib open/read/writelevel interface: 1GB/64KB = Minimum allocation unit.This may produce a minimum allocation unit that is larger thanwhat the developer desires (for cluster boundary buffer alignment,or other buffering, ect).One solution is to sub-divide the disk into smaller partitionsor "logical disks" on the single physical disk and format file systems over each of the partitions. (Then using this code youmay mount them.) If you used four equal sized partitions, thenthis method produces: 256MB/64KB = Minimum allocation unit. 256MB/64KB = Minimum allocation unit. 256MB/64KB = Minimum allocation unit. 256MB/64KB = Minimum allocation unit.This produces a smaller minimum allocation unit and may be better suited for optimal application file system performance.Each partition contains its own unique file system. As faras the file system level is concerned it is on a unique disk.Here is a picture showing the layout of a single disk containingmultiple MSDOS file systems:(Note, all ASCII pictures herein are best viewed with an 'equally sized characters' or 'fixed width' style font) +---------------------------------------------------------+ |<---------------------The entire disk------------------->| |M | |B<---C:---> | |R /---- First extended partition--------------\| | E<---D:---><-Rest of the ext part------------>| |P x | |A t E<---E:--->E<Rest of the ext part->| |R x x | |T t t<---------F:---------->| +---------------------------------------------------------+ (Ext == extended partition sector)A MS-DOS partition table resides within one sector on a harddisk. There is always one in the first sector of a hard diskpartitioned with FDISK.exe. There first partition table maycontain references to "extended" partition tables residing onother sectors if there are multiple partitions. The first sector of the disk is the starting point. Partition tablesare of the format:Offset from the beginning of the sector Description------------- ------------------------- 0x1be Partition 1 table entry (16 bytes) 0x1ce Partition 2 table entry (16 bytes) 0x1de Partition 3 table entry (16 bytes) 0x1ee Partition 4 table entry (16 bytes) 0x1fe Signature (0x55aa, 2 bytes)Individual MSDOS partition table entries are of the format:Offset Size Description------ ---- ------------------------------ 0x0 8 bits boot type 0x1 8 bits beginning sector head value 0x2 8 bits beginning sector (2 high bits of cylinder#) 0x3 8 bits beginning cylinder# (low order bits of cylinder#) 0x4 8 bits system indicator 0x5 8 bits ending sector head value 0x6 8 bits ending sector (2 high bits of cylinder#) 0x7 8 bits ending cylinder# (low order bits of cylinder#) 0x8 32 bits number of sectors preceding the partition 0xc 32 bits number of sectors in the partition In the partition table entry, the Sector/Cylinder (16bits)(offset 0x2 & 0x3) fields data are stored in the format: |7|6|5|4|3|2|1|0| The first 8 bits of offset 0x2. | | `------------ 6 least significant bit's contain the sector | | offset within cylinder. sector == 6 bits. | | `-`-------------- Two most significant (high order) bits of the cylinder value. |7|6|5|4|3|2|1|0| 2nd 8 bits (cylinder 0x3) `---------------- Eight least significant (low order) bits of the cylinder value.This format restricts partition entries to 10 cylinder bits & 6 sectorbits and 8 head bits. This is also the format used by the PC-AT BIOSInt13h functions, which is used by FDISK.exe dosPartLibAta/Scsi.c uses the following method of parsing the CHS valuesstored in the 0x2 & 0x3 partition table offsets into distinct values:Cyl = ((((dospt_startSec) & 0x00c0) << 2) | (((dospt_startSec) & 0xff00) >> 8));Hd = pPartTbl->dospt_startHead;Sec = (pPartTbl->dospt_startSec & 0x003f); (see DOS_PART_TBL struct typedef in dosFsLib.h)This produces individual CHS value from the values thatare contained within the MSDOS partition table entry. Definitions of CHS terms:CHS - Cylinder/Head/Sector. L-CHS - Logical - CHS (used by INT 13 AxH/FDISK.exe) 256 heads, 1024 cylinders, 63 sectors. max. LCHS allow ~8.4 GB addressable space.P-CHS - Physical CHS (used by physical ATA device) 16 heads, 65535 cylinders, 63 sectors. PCHS allow ~137GB addressable space. (VxWorks ataRawio() uses PCHS)LBA - Logical Block Address. ATA/SCSI absolute sector numbering scheme. LBA sector 0 == addresses the first sector on a device by definition. ATA devices may also support LBA at the device interface. ATA standard says that cylinder 0, head 0, sector 1 == LBA 0. LBA allows (~137GB) on an ATA device. The MSDOS "logical CHS" (LCHS) format combined with the Physical IDE/ATA CHS interface (PCHS) gives MSDOS the following addressing limitation: +------------+----------+----------------+ | BIOS INT13 | IDE/ATA | Combined Limit |+-----------------+------------+----------+----------------+ |Max Sectors/Track| 63 | 255 | 63 |+-----------------+------------+----------+----------------+|Max Heads | 256 | 16 | 16 |+-----------------+------------+----------+----------------+|Max Cylinders | 1024 | 65536 | 1024 |+-----------------+------------+----------+----------------+|Capacity | 8.4GB | 136.9GB | 528 MB |+-----------------+------------+----------+----------------+1024 x 16 x 63 X 512 bytes/sector = 528.48 MB limit.Cylinder bits : 10 = 1024Head bits : 4 = 16Sector bits : 6 (-1) = 63 (by convention, CHS sector numbering begins at #1, not #0; LBA begins at zero, which is CHS#1) To overcome the limitation. PC BIOS/OS vendors perform what is oftenreferred to as geometric or "drive" CHS translation to address more than 528MB, and to "address" cylinders above 1024.BIOS vendors offer CHS translation extensions that are basedaround the format of the PC-AT BIOS call "INT 0x13 function 0x8"aka "Get Current Drive Parameters" There are also two parametertables EDPT and FDPT set by the BIOS interfaces. EDPT is sometimesnot supported depending on the system BIOS. The FDPT is always supported on PC-AT compatible BIOS. Code is available for the x86VxWorks BSP to call INT13h F8h romInit.s BIOS call, which returnsthe FDPT. This is not needed when using LBA on newer systems.It is possible in the pc486/pc386 VxWorks BSP's to make anBIOS (INT13h F8H) call in romInit.s before the switch to protected mode. Sample romInit.s code demonstrating this will be provided upon request, contact johnx@wrs.com.requesting "Int13h romInit.s x86 code".There exists also some 3rd party software based disk overlayprograms (Such as OnTrack's Disk Manager,TM.) which uses asemi-proprietary strategy to support drives over 528MB. In most cases, the translated LCHS geometry is applied such thatall sectors are addressed at the same physical location as whenthe drive is used within an untranslated environment. However,not in all cases, and then there is a breakdown. Alas, there is not any standard for defining the altered geometry translationscheme, so compatibility issues will arise when moving drives fromone BIOS, Operating System, driver, and/or controller to another.VxWorks SCSI and ATA drivers communicate directly with thecontroller and do not use the BIOS. The VxWorks ATA drivermay address the full 136.9GB offered by ATA, and the full rangeoffered by SCSI. So this is not an issue for VxWorks. It shouldbe noted however, since all the partition table data will be stored in LCHS format.Here is an example of a typical PCHS to LCHS translation.(Note, all ASCII pictures herein are best viewed with an 'equally sized characters'/'fixed width' style font)+----------------+------------+----------------+-------------+--------+|Actual Cylinders|Actual Heads|Altered Cylinder|Altered Heads|Max Size|+----------------+------------+----------------+-------------+--------+| 1<C<=1024 | 1<H<=16 | C=C | H=H |528 MB |+----------------+------------+----------------+-------------+--------+| 1024<C<=2048 | 1<H<=16 | C=C/2 | H=H*2 | 1GB |+----------------+------------+----------------+-------------+--------+| 2048<C<=4096 | 1<H<=16 | C=C/4 | H=H*4 | 2.1GB |+----------------+------------+----------------+-------------+--------+| 4096<C<=8192 | 1<H<=16 | C=C/8 | H=H*8 | 4.2GB |+----------------+------------+----------------+-------------+--------+| 8192<C<=16384 | 1<H<=16 | C=C/16 | H=H*16 | 8.4GB |+----------------+------------+----------------+-------------+--------+| 16384<C<=32768 | 1<H<=8 | C=C/32 | H=H*32 | 8.4GB |+----------------+------------+----------------+-------------+--------+| 32768<C<=65536 | 1<H<=4 | C=C/64 | H=H*64 | 8.4GB |+----------------+------------+----------------+-------------+--------+Another type of translation always sets the sectors to 63, this produces different geometry than the above.+----------------+----------+---------+--------------+|Range | Sectors | Heads | Cylinders |+----------------+----------+---------+--------------+| 1<X<=528MB | 63 | 16 | X/(63*16*512)|+----------------+----------+---------+--------------+| 528MB<X<=1GB | 63 | 32 | X/(63*32*512)|+----------------+----------+---------+--------------+| 1GB<X<=2.1GB | 63 | 64 | X/(63*64*512)|+----------------+----------+---------+--------------+| 2.1GB<X<=4.2GB | 63 | 128 |X/(63*128*512)|+----------------+----------+---------+--------------+| 4.2GB<X<=8.4GB | 63 | 256 |X/(63*255*512)|+----------------+----------+---------+--------------+There are several MSDOS utilities (from Phoenix, and Western Digital, and more, such as wdtblchk.exe, and chkbios.exe) whichcan be used on PC's to check translations. These utilitiesuse BIOS calls to read the EPDT and FPDT to determine the PCHSand LCHS and LBA values for a given system. TRANSLATION ALGORITHMS:----------------------The algorithm used in this code for LBA to PCHS translation (in dosPartRdLba[Ata/Scsi]) is: PCHS_cylinder = LBA / (heads_per_cylinder * sectors_per_track) temp = LBA % (heads_per_cylinder * sectors_per_track)PCHS_head = temp / sectors_per_trackPCHS_sector = temp % sectors_per_track + 1The reverse, PCHS to LBA, is not implement but shown hereshould anyone need to implement it:LBA = (((cylinder * heads_per_cylinder + heads ) * sectors_per_track ) + sector - 1)Both of these can also be used with either LCHS or PCHS.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -