|
|
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.