|
|
1.1 ! root 1: /* ! 2: * Code extracted from ! 3: * linux/kernel/hd.c ! 4: * ! 5: * Copyright (C) 1991, 1992 Linus Torvalds ! 6: */ ! 7: ! 8: /* ! 9: * Thanks to Branko Lankester, [email protected], who found a bug ! 10: * in the early extended-partition checks and added DM partitions ! 11: */ ! 12: ! 13: #include <linux/config.h> ! 14: #include <linux/fs.h> ! 15: #include <linux/genhd.h> ! 16: #include <linux/kernel.h> ! 17: struct gendisk *gendisk_head = NULL; ! 18: ! 19: static int current_minor = 0; ! 20: extern int *blk_size[]; ! 21: /* ! 22: * Create devices for each logical partition in an extended partition. ! 23: * The logical partitions form a linked list, with each entry being ! 24: * a partition table with two entries. The first entry ! 25: * is the real data partition (with a start relative to the partition ! 26: * table start). The second is a pointer to the next logical partition ! 27: * (with a start relative to the entire extended partition). ! 28: * We do not create a Linux partition for the partition tables, but ! 29: * only for the actual data partitions. ! 30: */ ! 31: ! 32: static void extended_partition(struct gendisk *hd, int dev) ! 33: { ! 34: struct buffer_head *bh; ! 35: struct partition *p; ! 36: unsigned long first_sector, this_sector; ! 37: int mask = (1 << hd->minor_shift) - 1; ! 38: ! 39: first_sector = hd->part[MINOR(dev)].start_sect; ! 40: this_sector = first_sector; ! 41: ! 42: while (1) { ! 43: if ((current_minor & mask) >= (4 + hd->max_p)) ! 44: return; ! 45: if (!(bh = bread(dev,0,1024))) { ! 46: printk("Unable to read partition table of device %04x\n",dev); ! 47: return; ! 48: } ! 49: /* ! 50: * This block is from a device that we're about to stomp on. ! 51: * So make sure nobody thinks this block is usable. ! 52: */ ! 53: bh->b_dirt=0; ! 54: bh->b_uptodate=0; ! 55: if (*(unsigned short *) (bh->b_data+510) == 0xAA55) { ! 56: p = 0x1BE + (void *)bh->b_data; ! 57: /* ! 58: * Process the first entry, which should be the real ! 59: * data partition. ! 60: */ ! 61: if (p->sys_ind == EXTENDED_PARTITION || ! 62: !(hd->part[current_minor].nr_sects = p->nr_sects)) ! 63: goto done; /* shouldn't happen */ ! 64: hd->part[current_minor].start_sect = this_sector + p->start_sect; ! 65: printk(" Logical part %d start %d size %d end %d\n\r", ! 66: current_minor, hd->part[current_minor].start_sect, ! 67: hd->part[current_minor].nr_sects, ! 68: hd->part[current_minor].start_sect + ! 69: hd->part[current_minor].nr_sects - 1); ! 70: current_minor++; ! 71: p++; ! 72: /* ! 73: * Process the second entry, which should be a link ! 74: * to the next logical partition. Create a minor ! 75: * for this just long enough to get the next partition ! 76: * table. The minor will be reused for the real ! 77: * data partition. ! 78: */ ! 79: if (p->sys_ind != EXTENDED_PARTITION || ! 80: !(hd->part[current_minor].nr_sects = p->nr_sects)) ! 81: goto done; /* no more logicals in this partition */ ! 82: hd->part[current_minor].start_sect = first_sector + p->start_sect; ! 83: this_sector = first_sector + p->start_sect; ! 84: dev = ((hd->major) << 8) | current_minor; ! 85: brelse(bh); ! 86: } else ! 87: goto done; ! 88: } ! 89: done: ! 90: brelse(bh); ! 91: } ! 92: ! 93: static void check_partition(struct gendisk *hd, unsigned int dev) ! 94: { ! 95: int i, minor = current_minor; ! 96: struct buffer_head *bh; ! 97: struct partition *p; ! 98: unsigned long first_sector; ! 99: ! 100: first_sector = hd->part[MINOR(dev)].start_sect; ! 101: ! 102: if (!(bh = bread(dev,0,1024))) { ! 103: printk("Unable to read partition table of device %04x\n",dev); ! 104: return; ! 105: } ! 106: printk("%s%d :\n\r", hd->major_name, minor >> hd->minor_shift); ! 107: current_minor += 4; /* first "extra" minor */ ! 108: if (*(unsigned short *) (bh->b_data+510) == 0xAA55) { ! 109: p = 0x1BE + (void *)bh->b_data; ! 110: for (i=1 ; i<=4 ; minor++,i++,p++) { ! 111: if (!(hd->part[minor].nr_sects = p->nr_sects)) ! 112: continue; ! 113: hd->part[minor].start_sect = first_sector + p->start_sect; ! 114: printk(" part %d start %d size %d end %d \n\r", i, ! 115: hd->part[minor].start_sect, hd->part[minor].nr_sects, ! 116: hd->part[minor].start_sect + hd->part[minor].nr_sects - 1); ! 117: if ((current_minor & 0x3f) >= 60) ! 118: continue; ! 119: if (p->sys_ind == EXTENDED_PARTITION) { ! 120: extended_partition(hd, (hd->major << 8) | minor); ! 121: } ! 122: } ! 123: /* ! 124: * check for Disk Manager partition table ! 125: */ ! 126: if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) { ! 127: p = 0x1BE + (void *)bh->b_data; ! 128: for (i = 4 ; i < 16 ; i++, current_minor++) { ! 129: p--; ! 130: if ((current_minor & 0x3f) >= 60) ! 131: break; ! 132: if (!(p->start_sect && p->nr_sects)) ! 133: continue; ! 134: hd->part[current_minor].start_sect = p->start_sect; ! 135: hd->part[current_minor].nr_sects = p->nr_sects; ! 136: printk(" DM part %d start %d size %d end %d\n\r", ! 137: current_minor, ! 138: hd->part[current_minor].start_sect, ! 139: hd->part[current_minor].nr_sects, ! 140: hd->part[current_minor].start_sect + ! 141: hd->part[current_minor].nr_sects - 1); ! 142: } ! 143: } ! 144: } else ! 145: printk("Bad partition table on dev %04x\n",dev); ! 146: brelse(bh); ! 147: } ! 148: ! 149: static void setup_dev(struct gendisk *dev) ! 150: { ! 151: int i; ! 152: int j = dev->max_nr * dev->max_p; ! 153: int major = dev->major << 8; ! 154: int drive; ! 155: ! 156: ! 157: for (i = 0 ; i < j; i++) { ! 158: dev->part[i].start_sect = 0; ! 159: dev->part[i].nr_sects = 0; ! 160: } ! 161: dev->init(); ! 162: for (drive=0 ; drive<dev->nr_real ; drive++) { ! 163: current_minor = 1+(drive<<dev->minor_shift); ! 164: check_partition(dev, major+(drive<<dev->minor_shift)); ! 165: } ! 166: for (i=0 ; i < j ; i++) ! 167: dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); ! 168: blk_size[dev->major] = dev->sizes; ! 169: } ! 170: ! 171: /* This may be used only once, enforced by 'static int callable' */ ! 172: int sys_setup(void * BIOS) ! 173: { ! 174: static int callable = 1; ! 175: struct gendisk *p; ! 176: int nr=0; ! 177: ! 178: if (!callable) ! 179: return -1; ! 180: callable = 0; ! 181: ! 182: for (p = gendisk_head ; p ; p=p->next) { ! 183: setup_dev(p); ! 184: nr += p->nr_real; ! 185: } ! 186: ! 187: if (nr) ! 188: printk("Partition table%s ok.\n\r",(nr>1)?"s":""); ! 189: ! 190: #ifdef RAMDISK ! 191: rd_load(); ! 192: #endif ! 193: mount_root(); ! 194: return (0); ! 195: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.