⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genhd.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		printk(" unable to read partition table\n");		return -1;	}	data = bh->b_data;	/* In some cases we modify the geometry    */	/*  of the drive (below), so ensure that   */	/*  nobody else tries to re-use this data. */	bh->b_state = 0;#ifdef CONFIG_BLK_DEV_IDEcheck_table:#endif	if (*(unsigned short *)  (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {		brelse(bh);		return 0;	}	p = (struct partition *) (0x1be + data);#ifdef CONFIG_BLK_DEV_IDE	if (!tested_for_xlate++) {	/* Do this only once per disk */		/*		 * Look for various forms of IDE disk geometry translation		 */		extern int ide_xlate_1024(kdev_t, int, const char *);		unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));		if (SYS_IND(p) == EZD_PARTITION) {			/*			 * The remainder of the disk must be accessed using			 * a translated geometry that reduces the number of 			 * apparent cylinders to less than 1024 if possible.			 *			 * ide_xlate_1024() will take care of the necessary			 * adjustments to fool fdisk/LILO and partition check.			 */			if (ide_xlate_1024(dev, -1, " [EZD]")) {				data += 512;				goto check_table;			}		} else if (SYS_IND(p) == DM6_PARTITION) {			/*			 * Everything on the disk is offset by 63 sectors,			 * including a "new" MBR with its own partition table,			 * and the remainder of the disk must be accessed using			 * a translated geometry that reduces the number of 			 * apparent cylinders to less than 1024 if possible.			 *			 * ide_xlate_1024() will take care of the necessary			 * adjustments to fool fdisk/LILO and partition check.			 */			if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {				brelse(bh);				goto read_mbr;	/* start over with new MBR */			}		} else if (sig <= 0x1ae &&			   *(unsigned short *)(data + sig) == cpu_to_le16(0x55AA) &&			   (1 & *(unsigned char *)(data + sig + 2))) {			/* DM6 signature in MBR, courtesy of OnTrack */			(void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");		} else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {			/*			 * DM6 on other than the first (boot) drive			 */			(void) ide_xlate_1024(dev, 0, " [DM6:AUX]");		} else {			/*			 * Examine the partition table for common translations.			 * This is useful for drives in situations where the			 * translated geometry is unavailable from the BIOS.			 */			for (i = 0; i < 4; i++) {				struct partition *q = &p[i];				if (NR_SECTS(q)				   && (q->sector & 63) == 1				   && (q->end_sector & 63) == 63) {					unsigned int heads = q->end_head + 1;					if (heads == 32 || heads == 64 ||					    heads == 128 || heads == 240 ||					    heads == 255) {						(void) ide_xlate_1024(dev, heads, " [PTBL]");						break;					}				}			}		}	}#endif	/* CONFIG_BLK_DEV_IDE */	current_minor += 4;  /* first "extra" minor (for extended partitions) */	for (i=1 ; i<=4 ; minor++,i++,p++) {		if (!NR_SECTS(p))			continue;               add_partition(hd, minor, first_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size,                		     ptype(SYS_IND(p)));		if (is_extended_partition(p)) {			printk(" <");			/*			 * If we are rereading the partition table, we need			 * to set the size of the partition so that we will			 * be able to bread the block containing the extended			 * partition info.			 */			hd->sizes[minor] = hd->part[minor].nr_sects 			  	>> (BLOCK_SIZE_BITS - 9);			extended_partition(hd, MKDEV(hd->major, minor));			printk(" >");			/* prevent someone doing mkfs or mkswap on an			   extended partition, but leave room for LILO */			if (hd->part[minor].nr_sects > 2)				hd->part[minor].nr_sects = 2;		}#ifdef CONFIG_BSD_DISKLABEL			/* tag first disklabel for late recognition */		if (SYS_IND(p) == BSD_PARTITION || SYS_IND(p) == NETBSD_PARTITION) {			printk("!");			if (!bsd_kdev)				bsd_kdev = MKDEV(hd->major, minor);		} else if (SYS_IND(p) == OPENBSD_PARTITION) {			printk("!");			if (!bsd_kdev) {				bsd_kdev = MKDEV(hd->major, minor);				bsd_maxpart = OPENBSD_MAXPARTITIONS;			}		}#endif#ifdef CONFIG_UNIXWARE_DISKLABEL		if (SYS_IND(p) == UNIXWARE_PARTITION)			unixware_partition(hd, MKDEV(hd->major, minor));#endif#ifdef CONFIG_SOLARIS_X86_PARTITION		/* james@bpgc.com: Solaris has a nasty indicator: 0x82		 * which also means linux swap.  For that reason, all		 * of the prints are done inside the		 * solaris_x86_partition routine */		if(SYS_IND(p) == SOLARIS_X86_PARTITION) {			solaris_x86_partition(hd, MKDEV(hd->major, minor),					      first_sector+START_SECT(p));		}#endif	}#ifdef CONFIG_BSD_DISKLABEL	if (bsd_kdev) {		printk(" <");		bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart);		printk(" >");	}#endif	/*	 *  Check for old-style Disk Manager partition table	 */	if (*(unsigned short *) (data+0xfc) == cpu_to_le16(MSDOS_LABEL_MAGIC)) {		p = (struct partition *) (0x1be + data);		for (i = 4 ; i < 16 ; i++, current_minor++) {			p--;			if ((current_minor & mask) == 0)				break;			if (!(START_SECT(p) && NR_SECTS(p)))				continue;			add_partition(hd, current_minor, START_SECT(p),					NR_SECTS(p), 0);		}	}	printk("\n");	brelse(bh);	return 1;}#endif /* CONFIG_MSDOS_PARTITION */#ifdef CONFIG_OSF_PARTITIONstatic int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector){	int i;	int mask = (1 << hd->minor_shift) - 1;	struct buffer_head *bh;	struct disklabel {		u32 d_magic;		u16 d_type,d_subtype;		u8 d_typename[16];		u8 d_packname[16];		u32 d_secsize;		u32 d_nsectors;		u32 d_ntracks;		u32 d_ncylinders;		u32 d_secpercyl;		u32 d_secprtunit;		u16 d_sparespertrack;		u16 d_sparespercyl;		u32 d_acylinders;		u16 d_rpm, d_interleave, d_trackskew, d_cylskew;		u32 d_headswitch, d_trkseek, d_flags;		u32 d_drivedata[5];		u32 d_spare[5];		u32 d_magic2;		u16 d_checksum;		u16 d_npartitions;		u32 d_bbsize, d_sbsize;		struct d_partition {			u32 p_size;			u32 p_offset;			u32 p_fsize;			u8  p_fstype;			u8  p_frag;			u16 p_cpg;		} d_partitions[8];	} * label;	struct d_partition * partition;#define DISKLABELMAGIC (0x82564557UL)	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {		printk("unable to read partition table\n");		return -1;	}	label = (struct disklabel *) (bh->b_data+64);	partition = label->d_partitions;	if (label->d_magic != DISKLABELMAGIC) {		brelse(bh);		return 0;	}	if (label->d_magic2 != DISKLABELMAGIC) {		brelse(bh);		return 0;	}	for (i = 0 ; i < label->d_npartitions; i++, partition++) {		if ((current_minor & mask) == 0)		        break;		if (partition->p_size)			add_partition(hd, current_minor,				first_sector+partition->p_offset,				partition->p_size, 0);		current_minor++;	}	printk("\n");	brelse(bh);	return 1;}#endif /* CONFIG_OSF_PARTITION */#ifdef CONFIG_SUN_PARTITIONstatic int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector){	int i, csum;	unsigned short *ush;	struct buffer_head *bh;	struct sun_disklabel {		unsigned char info[128];   /* Informative text string */		unsigned char spare0[14];		struct sun_disklabelinfo {			unsigned char spare1;			unsigned char id;			unsigned char spare2;			unsigned char flags;		} infos[8];		unsigned char spare1[246];  /* Boot information etc. */		unsigned short rspeed;     /* Disk rotational speed */		unsigned short pcylcount;  /* Physical cylinder count */		unsigned short sparecyl;   /* extra sects per cylinder */		unsigned char spare2[4];   /* More magic... */		unsigned short ilfact;     /* Interleave factor */		unsigned short ncyl;       /* Data cylinder count */		unsigned short nacyl;      /* Alt. cylinder count */		unsigned short ntrks;      /* Tracks per cylinder */		unsigned short nsect;      /* Sectors per track */		unsigned char spare3[4];   /* Even more magic... */		struct sun_partition {			__u32 start_cylinder;			__u32 num_sectors;		} partitions[8];		unsigned short magic;      /* Magic number */		unsigned short csum;       /* Label xor'd checksum */	} * label;			struct sun_partition *p;	unsigned long spc;#define SUN_LABEL_MAGIC          0xDABE	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {		printk("Dev %s: unable to read partition table\n",		       kdevname(dev));		return -1;	}	label = (struct sun_disklabel *) bh->b_data;	p = label->partitions;	if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {		printk("Dev %s Sun disklabel: bad magic %04x\n",		       kdevname(dev), be16_to_cpu(label->magic));		brelse(bh);		return 0;	}	/* Look at the checksum */	ush = ((unsigned short *) (label+1)) - 1;	for(csum = 0; ush >= ((unsigned short *) label);)		csum ^= *ush--;	if(csum) {		printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",		       kdevname(dev));		brelse(bh);		return 0;	}	/* All Sun disks have 8 partition entries */	spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);	for(i=0; i < 8; i++, p++) {		unsigned long st_sector;		int num_sectors;		st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;		num_sectors = be32_to_cpu(p->num_sectors);		if (num_sectors)			add_partition(hd, current_minor, st_sector,					num_sectors, ptype(label->infos[i].id));		current_minor++;	}	printk("\n");	brelse(bh);	return 1;}#endif /* CONFIG_SUN_PARTITION */#ifdef CONFIG_SGI_PARTITIONstatic int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector){	int i, csum, magic;	unsigned int *ui, start, blocks, cs;	struct buffer_head *bh;	struct sgi_disklabel {		int magic_mushroom;         /* Big fat spliff... */		short root_part_num;        /* Root partition number */		short swap_part_num;        /* Swap partition number */		char boot_file[16];         /* Name of boot file for ARCS */		unsigned char _unused0[48]; /* Device parameter useless crapola.. */		struct sgi_volume {			char name[8];       /* Name of volume */			int  block_num;     /* Logical block number */			int  num_bytes;     /* How big, in bytes */		} volume[15];		struct sgi_partition {			int num_blocks;     /* Size in logical blocks */			int first_block;    /* First logical block */			int type;           /* Type of this partition */		} partitions[16];		int csum;                   /* Disk label checksum */		int _unused1;               /* Padding */	} *label;	struct sgi_partition *p;#define SGI_LABEL_MAGIC 0x0be5a941	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {		printk("Dev %s: unable to read partition table\n", kdevname(dev));		return -1;	}	label = (struct sgi_disklabel *) bh->b_data;	p = &label->partitions[0];	magic = label->magic_mushroom;	if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {		printk("Dev %s SGI disklabel: bad magic %08x\n",		       kdevname(dev), magic);		brelse(bh);		return 0;	}	ui = ((unsigned int *) (label + 1)) - 1;	for(csum = 0; ui >= ((unsigned int *) label);) {		cs = *ui--;		csum += be32_to_cpu(cs);	}	if(csum) {		printk("Dev %s SGI disklabel: csum bad, label corrupted\n",		       kdevname(dev));		brelse(bh);		return 0;	}	/* All SGI disk labels have 16 partitions, disks under Linux only	 * have 15 minor's.  Luckily there are always a few zero length	 * partitions which we don't care about so we never overflow the	 * current_minor.	 */	for(i = 0; i < 16; i++, p++) {		blocks = be32_to_cpu(p->num_blocks);		start  = be32_to_cpu(p->first_block);		if(!blocks)			continue;		add_partition(hd, current_minor, start, blocks, 0);		current_minor++;	}	printk("\n");	brelse(bh);	return 1;}#endif#ifdef CONFIG_AMIGA_PARTITION#include <linux/affs_hardblocks.h>static __inline__ u32checksum_block(u32 *m, int size){	u32 sum = 0;	while (size--)		sum += htonl(*m++);	return sum;}static intamiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector){	struct buffer_head	*bh;	struct RigidDiskBlock	*rdb;	struct PartitionBlock	*pb;	int			 start_sect;	int			 nr_sects;	int			 blk;	int			 part, res;	int			 old_blocksize;	int			 blocksize;	old_blocksize = get_ptable_blocksize(dev);	if (hardsect_size[MAJOR(dev)] != NULL)		blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];	else		blocksize = 512;	set_blocksize(dev,blocksize);	res = 0;	for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {		if(!(bh = bread(dev,blk,blocksize))) {			printk("Dev %s: unable to read RDB block %d\n",			       kdevname(dev),blk);			goto rdb_done;		}		if (*(u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) {			rdb = (struct RigidDiskBlock *)bh->b_data;			if (checksum_block((u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) {				/* Try again with 0xdc..0xdf zeroed, Windows might have				 * trashed it.				 */				*(u32 *)(&bh->b_data[0xdc]) = 0;				if (checksum_block((u32 *)bh->b_data,						htonl(rdb->rdb_SummedLongs) & 0x7F)) {					brelse(bh);					printk("Dev %s: RDB in block %d has bad checksum\n",					       kdevname(dev),blk);					continue;				}				printk("Warning: Trashed word at 0xd0 in block %d "					"ignored in checksum calculation\n",blk);			}			printk(" RDSK");			blk = htonl(rdb->rdb_PartitionList);			brelse(bh);			for (part = 1; blk > 0 && part <= 16; part++) {				if (!(bh = bread(dev,blk,blocksize))) {					printk("Dev %s: unable to read partition block %d\n",						       kdevname(dev),blk);					goto rdb_done;				}				pb  = (struct PartitionBlock *)bh->b_data;				blk = htonl(pb->pb_Next);				if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block(				    (u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) {					/* Tell Kernel about it */					if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 -							  htonl(pb->pb_Environment[9])) *							 htonl(pb->pb_Environment[3]) *							 htonl(pb->pb_Environment[5]))) {						brelse(bh);						continue;					}					start_sect = htonl(pb->pb_Environment[9]) *						     htonl(pb->pb_Environment[3]) *						     htonl(pb->pb_Environment[5]);					add_partition(hd,current_minor,							start_sect,nr_sects,0);					current_minor++;					res = 1;				}				brelse(bh);			}			printk("\n");		}		else			brelse(bh);	}rdb_done:	set_blocksize(dev,old_blocksize);	return res;}#endif /* CONFIG_AMIGA_PARTITION */#ifdef CONFIG_MAC_PARTITION

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -