|
|
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",
1.1.1.2 ! root 66: mask & current_minor, hd->part[current_minor].start_sect,
1.1 root 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;
1.1.1.2 ! root 99: int mask = (1 << hd->minor_shift) - 1;
1.1 root 100:
101: first_sector = hd->part[MINOR(dev)].start_sect;
102:
103: if (!(bh = bread(dev,0,1024))) {
104: printk("Unable to read partition table of device %04x\n",dev);
105: return;
106: }
1.1.1.2 ! root 107: printk("%s%c :\n\r", hd->major_name, 'a'+(minor >> hd->minor_shift));
1.1 root 108: current_minor += 4; /* first "extra" minor */
109: if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
110: p = 0x1BE + (void *)bh->b_data;
111: for (i=1 ; i<=4 ; minor++,i++,p++) {
112: if (!(hd->part[minor].nr_sects = p->nr_sects))
113: continue;
114: hd->part[minor].start_sect = first_sector + p->start_sect;
115: printk(" part %d start %d size %d end %d \n\r", i,
116: hd->part[minor].start_sect, hd->part[minor].nr_sects,
117: hd->part[minor].start_sect + hd->part[minor].nr_sects - 1);
118: if ((current_minor & 0x3f) >= 60)
119: continue;
120: if (p->sys_ind == EXTENDED_PARTITION) {
121: extended_partition(hd, (hd->major << 8) | minor);
122: }
123: }
124: /*
125: * check for Disk Manager partition table
126: */
127: if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
128: p = 0x1BE + (void *)bh->b_data;
129: for (i = 4 ; i < 16 ; i++, current_minor++) {
130: p--;
1.1.1.2 ! root 131: if ((current_minor & mask) >= mask-2)
1.1 root 132: break;
133: if (!(p->start_sect && p->nr_sects))
134: continue;
135: hd->part[current_minor].start_sect = p->start_sect;
136: hd->part[current_minor].nr_sects = p->nr_sects;
137: printk(" DM part %d start %d size %d end %d\n\r",
1.1.1.2 ! root 138: current_minor & mask,
1.1 root 139: hd->part[current_minor].start_sect,
140: hd->part[current_minor].nr_sects,
141: hd->part[current_minor].start_sect +
142: hd->part[current_minor].nr_sects - 1);
143: }
144: }
145: } else
146: printk("Bad partition table on dev %04x\n",dev);
147: brelse(bh);
148: }
149:
150: static void setup_dev(struct gendisk *dev)
151: {
152: int i;
153: int j = dev->max_nr * dev->max_p;
154: int major = dev->major << 8;
155: int drive;
156:
157:
158: for (i = 0 ; i < j; i++) {
159: dev->part[i].start_sect = 0;
160: dev->part[i].nr_sects = 0;
161: }
162: dev->init();
163: for (drive=0 ; drive<dev->nr_real ; drive++) {
164: current_minor = 1+(drive<<dev->minor_shift);
165: check_partition(dev, major+(drive<<dev->minor_shift));
166: }
167: for (i=0 ; i < j ; i++)
168: dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
169: blk_size[dev->major] = dev->sizes;
170: }
171:
172: /* This may be used only once, enforced by 'static int callable' */
173: int sys_setup(void * BIOS)
174: {
175: static int callable = 1;
176: struct gendisk *p;
177: int nr=0;
178:
179: if (!callable)
180: return -1;
181: callable = 0;
182:
183: for (p = gendisk_head ; p ; p=p->next) {
184: setup_dev(p);
185: nr += p->nr_real;
186: }
187:
188: if (nr)
189: printk("Partition table%s ok.\n\r",(nr>1)?"s":"");
190:
191: #ifdef RAMDISK
192: rd_load();
193: #endif
194: mount_root();
195: return (0);
196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.