📄 drvlib.c
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/kernel/drvlib.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
09500 /* IBM device driver utility functions. Author: Kees J. Bot
09501 * 7 Dec 1995
09502 * Entry point:
09503 * partition: partition a disk to the partition table(s) on it.
09504 */
09505
09506 #include "kernel.h"
09507 #include "driver.h"
09508 #include "drvlib.h"
09509
09510
09511 FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
09512 unsigned long extbase) );
09513 FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device,
09514 unsigned long offset, struct part_entry *table) );
09515 FORWARD _PROTOTYPE( void sort, (struct part_entry *table) );
09516
09517
09518 /*============================================================================*
09519 * partition *
09520 *============================================================================*/
09521 PUBLIC void partition(dp, device, style)
09522 struct driver *dp; /* device dependent entry points */
09523 int device; /* device to partition */
09524 int style; /* partitioning style: floppy, primary, sub. */
09525 {
09526 /* This routine is called on first open to initialize the partition tables
09527 * of a device. It makes sure that each partition falls safely within the
09528 * device's limits. Depending on the partition style we are either making
09529 * floppy partitions, primary partitions or subpartitions. Only primary
09530 * partitions are sorted, because they are shared with other operating
09531 * systems that expect this.
09532 */
09533 struct part_entry table[NR_PARTITIONS], *pe;
09534 int disk, par;
09535 struct device *dv;
09536 unsigned long base, limit, part_limit;
09537
09538 /* Get the geometry of the device to partition */
09539 if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV || dv->dv_size == 0) return;
09540 base = dv->dv_base >> SECTOR_SHIFT;
09541 limit = base + (dv->dv_size >> SECTOR_SHIFT);
09542
09543 /* Read the partition table for the device. */
09544 if (!get_part_table(dp, device, 0L, table)) return;
09545
09546 /* Compute the device number of the first partition. */
09547 switch (style) {
09548 case P_FLOPPY:
09549 device += MINOR_fd0a;
09550 break;
09551 case P_PRIMARY:
09552 sort(table); /* sort a primary partition table */
09553 device += 1;
09554 break;
09555 case P_SUB:
09556 disk = device / DEV_PER_DRIVE;
09557 par = device % DEV_PER_DRIVE - 1;
09558 device = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
09559 }
09560
09561 /* Find an array of devices. */
09562 if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV) return;
09563
09564 /* Set the geometry of the partitions from the partition table. */
09565 for (par = 0; par < NR_PARTITIONS; par++, dv++) {
09566 /* Shrink the partition to fit within the device. */
09567 pe = &table[par];
09568 part_limit = pe->lowsec + pe->size;
09569 if (part_limit < pe->lowsec) part_limit = limit;
09570 if (part_limit > limit) part_limit = limit;
09571 if (pe->lowsec < base) pe->lowsec = base;
09572 if (part_limit < pe->lowsec) part_limit = pe->lowsec;
09573
09574 dv->dv_base = pe->lowsec << SECTOR_SHIFT;
09575 dv->dv_size = (part_limit - pe->lowsec) << SECTOR_SHIFT;
09576
09577 if (style == P_PRIMARY) {
09578 /* Each Minix primary partition can be subpartitioned. */
09579 if (pe->sysind == MINIX_PART)
09580 partition(dp, device + par, P_SUB);
09581
09582 /* An extended partition has logical partitions. */
09583 if (pe->sysind == EXT_PART)
09584 extpartition(dp, device + par, pe->lowsec);
09585 }
09586 }
09587 }
09590 /*============================================================================*
09591 * extpartition *
09592 *============================================================================*/
09593 PRIVATE void extpartition(dp, extdev, extbase)
09594 struct driver *dp; /* device dependent entry points */
09595 int extdev; /* extended partition to scan */
09596 unsigned long extbase; /* sector offset of the base extended partition */
09597 {
09598 /* Extended partitions cannot be ignored alas, because people like to move
09599 * files to and from DOS partitions. Avoid reading this code, it's no fun.
09600 */
09601 struct part_entry table[NR_PARTITIONS], *pe;
09602 int subdev, disk, par;
09603 struct device *dv;
09604 unsigned long offset, nextoffset;
09605
09606 disk = extdev / DEV_PER_DRIVE;
09607 par = extdev % DEV_PER_DRIVE - 1;
09608 subdev = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
09609
09610 offset = 0;
09611 do {
09612 if (!get_part_table(dp, extdev, offset, table)) return;
09613 sort(table);
09614
09615 /* The table should contain one logical partition and optionally
09616 * another extended partition. (It's a linked list.)
09617 */
09618 nextoffset = 0;
09619 for (par = 0; par < NR_PARTITIONS; par++) {
09620 pe = &table[par];
09621 if (pe->sysind == EXT_PART) {
09622 nextoffset = pe->lowsec;
09623 } else
09624 if (pe->sysind != NO_PART) {
09625 if ((dv = (*dp->dr_prepare)(subdev)) == NIL_DEV) return;
09626
09627 dv->dv_base = (extbase + offset
09628 + pe->lowsec) << SECTOR_SHIFT;
09629 dv->dv_size = pe->size << SECTOR_SHIFT;
09630
09631 /* Out of devices? */
09632 if (++subdev % NR_PARTITIONS == 0) return;
09633 }
09634 }
09635 } while ((offset = nextoffset) != 0);
09636 }
09639 /*============================================================================*
09640 * get_part_table *
09641 *============================================================================*/
09642 PRIVATE int get_part_table(dp, device, offset, table)
09643 struct driver *dp;
09644 int device;
09645 unsigned long offset; /* sector offset to the table */
09646 struct part_entry *table; /* four entries */
09647 {
09648 /* Read the partition table for the device, return true iff there were no
09649 * errors.
09650 */
09651 message mess;
09652
09653 mess.DEVICE = device;
09654 mess.POSITION = offset << SECTOR_SHIFT;
09655 mess.COUNT = SECTOR_SIZE;
09656 mess.ADDRESS = (char *) tmp_buf;
09657 mess.PROC_NR = proc_number(proc_ptr);
09658 mess.m_type = DEV_READ;
09659
09660 if (do_rdwt(dp, &mess) != SECTOR_SIZE) {
09661 printf("%s: can't read partition table\n", (*dp->dr_name)());
09662 return 0;
09663 }
09664 if (tmp_buf[510] != 0x55 || tmp_buf[511] != 0xAA) {
09665 /* Invalid partition table. */
09666 return 0;
09667 }
09668 memcpy(table, (tmp_buf + PART_TABLE_OFF), NR_PARTITIONS * sizeof(table[0]));
09669 return 1;
09670 }
09673 /*===========================================================================*
09674 * sort *
09675 *===========================================================================*/
09676 PRIVATE void sort(table)
09677 struct part_entry *table;
09678 {
09679 /* Sort a partition table. */
09680 struct part_entry *pe, tmp;
09681 int n = NR_PARTITIONS;
09682
09683 do {
09684 for (pe = table; pe < table + NR_PARTITIONS-1; pe++) {
09685 if (pe[0].sysind == NO_PART
09686 || (pe[0].lowsec > pe[1].lowsec
09687 && pe[1].sysind != NO_PART)) {
09688 tmp = pe[0]; pe[0] = pe[1]; pe[1] = tmp;
09689 }
09690 }
09691 } while (--n > 0);
09692 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -