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

📄 genhd.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <linux/ctype.h>/* * Code to understand MacOS partition tables. */#define MAC_PARTITION_MAGIC	0x504d/* type field value for A/UX or other Unix partitions */#define APPLE_AUX_TYPE	"Apple_UNIX_SVR2"struct mac_partition {	__u16	signature;	/* expected to be MAC_PARTITION_MAGIC */	__u16	res1;	__u32	map_count;	/* # blocks in partition map */	__u32	start_block;	/* absolute starting block # of partition */	__u32	block_count;	/* number of blocks in partition */	char	name[32];	/* partition name */	char	type[32];	/* string type description */	__u32	data_start;	/* rel block # of first data block */	__u32	data_count;	/* number of data blocks */	__u32	status;		/* partition status bits */	__u32	boot_start;	__u32	boot_size;	__u32	boot_load;	__u32	boot_load2;	__u32	boot_entry;	__u32	boot_entry2;	__u32	boot_cksum;	char	processor[16];	/* identifies ISA of boot */	/* there is more stuff after this that we don't need */};#define MAC_STATUS_BOOTABLE	8	/* partition is bootable */#define MAC_DRIVER_MAGIC	0x4552/* Driver descriptor structure, in block 0 */struct mac_driver_desc {	__u16	signature;	/* expected to be MAC_DRIVER_MAGIC */	__u16	block_size;	__u32	block_count;    /* ... more stuff */};static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec){	struct buffer_head *bh;	int blk, blocks_in_map;	int dev_bsize, dev_pos, pos;	unsigned secsize;#ifdef CONFIG_PPC	int first_bootable = 1;#endif	struct mac_partition *part;	struct mac_driver_desc *md;	dev_bsize = get_ptable_blocksize(dev);	dev_pos = 0;	/* Get 0th block and look at the first partition map entry. */	if ((bh = bread(dev, 0, dev_bsize)) == 0) {	    printk("%s: error reading partition table\n",		   kdevname(dev));	    return -1;	}	md = (struct mac_driver_desc *) bh->b_data;	if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {		brelse(bh);		return 0;	}	secsize = be16_to_cpu(md->block_size);	if (secsize >= dev_bsize) {		brelse(bh);		dev_pos = secsize;		if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {			printk("%s: error reading partition table\n",			       kdevname(dev));			return -1;		}	}	part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {		brelse(bh);		return 0;		/* not a MacOS disk */	}	blocks_in_map = be32_to_cpu(part->map_count);	for (blk = 1; blk <= blocks_in_map; ++blk) {		pos = blk * secsize;		if (pos >= dev_pos + dev_bsize) {			brelse(bh);			dev_pos = pos;			if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {				printk("%s: error reading partition table\n",				       kdevname(dev));				return -1;			}		}		part = (struct mac_partition *) (bh->b_data + pos - dev_pos);		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)			break;		blocks_in_map = be32_to_cpu(part->map_count);		add_partition(hd, current_minor,			fsec + be32_to_cpu(part->start_block) * (secsize/512),			be32_to_cpu(part->block_count) * (secsize/512), 0);#ifdef CONFIG_PPC		/*		 * If this is the first bootable partition, tell the		 * setup code, in case it wants to make this the root.		 */		if ( (_machine == _MACH_Pmac) && first_bootable		    && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)		    && strcasecmp(part->processor, "powerpc") == 0) {			note_bootable_part(dev, blk);			first_bootable = 0;		}#endif /* CONFIG_PPC */		++current_minor;	}	brelse(bh);	printk("\n");	return 1;}#endif /* CONFIG_MAC_PARTITION */#ifdef CONFIG_ATARI_PARTITION#include <asm/atari_rootsec.h>/* ++guenther: this should be settable by the user ("make config")?. */#define ICD_PARTSstatic int atari_partition (struct gendisk *hd, kdev_t dev,			    unsigned long first_sector){  int minor = current_minor, m_lim = current_minor + hd->max_p;  struct buffer_head *bh;  struct rootsector *rs;  struct partition_info *pi;  ulong extensect;#ifdef ICD_PARTS  int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */#endif  bh = bread (dev, 0, get_ptable_blocksize(dev));  if (!bh)    {      printk (" unable to read block 0\n");      return -1;    }  rs = (struct rootsector *) bh->b_data;  pi = &rs->part[0];  printk (" AHDI");  for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)    {      if (pi->flg & 1)	/* active partition */	{	  if (memcmp (pi->id, "XGM", 3) == 0)	    /* extension partition */	    {	      struct rootsector *xrs;	      struct buffer_head *xbh;	      ulong partsect;#ifdef ICD_PARTS	      part_fmt = 1;#endif	      printk(" XGM<");	      partsect = extensect = pi->st;	      while (1)		{		  xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev));		  if (!xbh)		    {		      printk (" block %ld read failed\n", partsect);		      brelse(bh);		      return 0;		    }		  if (partsect & 1)		    xrs = (struct rootsector *) &xbh->b_data[512];		  else		    xrs = (struct rootsector *) &xbh->b_data[0];		  /* ++roman: sanity check: bit 0 of flg field must be set */		  if (!(xrs->part[0].flg & 1)) {		    printk( "\nFirst sub-partition in extended partition is not valid!\n" );		    break;		  }		  add_partition(hd, minor, partsect + xrs->part[0].st,				xrs->part[0].siz, 0);		  if (!(xrs->part[1].flg & 1)) {		    /* end of linked partition list */		    brelse( xbh );		    break;		  }		  if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {		    printk( "\nID of extended partition is not XGM!\n" );		    brelse( xbh );		    break;		  }		  partsect = xrs->part[1].st + extensect;		  brelse (xbh);		  minor++;		  if (minor >= m_lim) {		    printk( "\nMaximum number of partitions reached!\n" );		    break;		  }		}	      printk(" >");	    }	  else	    {	      /* we don't care about other id's */	      add_partition (hd, minor, pi->st, pi->siz, 0);	    }	}    }#ifdef ICD_PARTS  if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */  {    pi = &rs->icdpart[0];    /* sanity check: no ICD format if first partition invalid */    if (memcmp (pi->id, "GEM", 3) == 0 ||        memcmp (pi->id, "BGM", 3) == 0 ||        memcmp (pi->id, "LNX", 3) == 0 ||        memcmp (pi->id, "SWP", 3) == 0 ||        memcmp (pi->id, "RAW", 3) == 0 )    {      printk(" ICD<");      for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)      {        /* accept only GEM,BGM,RAW,LNX,SWP partitions */        if (pi->flg & 1 &&             (memcmp (pi->id, "GEM", 3) == 0 ||             memcmp (pi->id, "BGM", 3) == 0 ||             memcmp (pi->id, "LNX", 3) == 0 ||             memcmp (pi->id, "SWP", 3) == 0 ||             memcmp (pi->id, "RAW", 3) == 0) )        {          part_fmt = 2;	  add_partition (hd, minor, pi->st, pi->siz, 0);        }      }      printk(" >");    }  }#endif  brelse (bh);  printk ("\n");  return 1;}#endif /* CONFIG_ATARI_PARTITION */#ifdef CONFIG_ULTRIX_PARTITIONstatic int ultrix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector){	int i, minor = current_minor;	struct buffer_head *bh;	struct ultrix_disklabel {		long	pt_magic;	/* magic no. indicating part. info exits */		int	pt_valid;	/* set by driver if pt is current */		struct  pt_info {			int		pi_nblocks; /* no. of sectors */			unsigned long	pi_blkoff;  /* block offset for start */		} pt_part[8];	} *label;#define PT_MAGIC	0x032957	/* Partition magic number */#define PT_VALID	1		/* Indicates if struct is valid */#define	SBLOCK	((unsigned long)((16384 - sizeof(struct ultrix_disklabel)) \                  /get_ptable_blocksize(dev)))	bh = bread (dev, SBLOCK, get_ptable_blocksize(dev));	if (!bh) {		printk (" unable to read block 0x%lx\n", SBLOCK);		return -1;	}		label = (struct ultrix_disklabel *)(bh->b_data                                            + get_ptable_blocksize(dev)                                            - sizeof(struct ultrix_disklabel));	if (label->pt_magic == PT_MAGIC && label->pt_valid == PT_VALID) {		for (i=0; i<8; i++, minor++)			if (label->pt_part[i].pi_nblocks)				add_partition(hd, minor, 					      label->pt_part[i].pi_blkoff,					      label->pt_part[i].pi_nblocks);		brelse(bh);		printk ("\n");		return 1;	} else {		brelse(bh);		return 0;	}}#endif /* CONFIG_ULTRIX_PARTITION */static void check_partition(struct gendisk *hd, kdev_t dev){	static int first_time = 1;	unsigned long first_sector;	char buf[MAX_DISKNAME_LEN];	if (first_time)		printk("Partition check:\n");	first_time = 0;	first_sector = hd->part[MINOR(dev)].start_sect;	/*	 * This is a kludge to allow the partition check to be	 * skipped for specific drives (e.g. IDE CD-ROM drives)	 */	if ((int)first_sector == -1) {		hd->part[MINOR(dev)].start_sect = 0;		return;	}	printk(" %s:", disk_name(hd, MINOR(dev), buf));#ifdef CONFIG_MSDOS_PARTITION	if (msdos_partition(hd, dev, first_sector))		return;#endif#ifdef CONFIG_OSF_PARTITION	if (osf_partition(hd, dev, first_sector))		return;#endif#ifdef CONFIG_SUN_PARTITION	if(sun_partition(hd, dev, first_sector))		return;#endif#ifdef CONFIG_AMIGA_PARTITION	if(amiga_partition(hd, dev, first_sector))		return;#endif#ifdef CONFIG_ATARI_PARTITION	if(atari_partition(hd, dev, first_sector))		return;#endif#ifdef CONFIG_MAC_PARTITION	if (mac_partition(hd, dev, first_sector))		return;#endif#ifdef CONFIG_SGI_PARTITION	if(sgi_partition(hd, dev, first_sector))		return;#endif#ifdef CONFIG_ULTRIX_PARTITION	if(ultrix_partition(hd, dev, first_sector))		return;#endif	printk(" unknown partition table\n");}/* This function is used to re-read partition tables for removable disks.   Much of the cleanup from the old partition tables should have already been   done *//* This function will re-read the partition tables for a given device,and set things back up again.  There are some important caveats,however.  You must ensure that no one is using the device, and no onecan start using the device while this function is being executed. */void resetup_one_dev(struct gendisk *dev, int drive){	int i;	int first_minor	= drive << dev->minor_shift;	int end_minor	= first_minor + dev->max_p;	blk_size[dev->major] = NULL;	current_minor = 1 + first_minor;	check_partition(dev, MKDEV(dev->major, first_minor)); 	/* 	 * We need to set the sizes array before we will be able to access 	 * any of the partitions on this device. 	 */	if (dev->sizes != NULL) {	/* optional safeguard in ll_rw_blk.c */		for (i = first_minor; i < end_minor; i++)			dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);		blk_size[dev->major] = dev->sizes;	}}static inline void setup_dev(struct gendisk *dev){	int i, drive;	int end_minor	= dev->max_nr * dev->max_p;	blk_size[dev->major] = NULL;	for (i = 0 ; i < end_minor; i++) {		dev->part[i].start_sect = 0;		dev->part[i].nr_sects = 0;	}	dev->init(dev);		for (drive = 0 ; drive < dev->nr_real ; drive++) {		int first_minor	= drive << dev->minor_shift;		current_minor = 1 + first_minor;		check_partition(dev, MKDEV(dev->major, first_minor));	}	if (dev->sizes != NULL) {	/* optional safeguard in ll_rw_blk.c */		for (i = 0; i < end_minor; i++)			dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);		blk_size[dev->major] = dev->sizes;	}}__initfunc(void device_setup(void)){	extern void console_map_init(void);	extern void cpqarray_init(void);#ifdef CONFIG_PARPORT	extern int parport_init(void);#endif#ifdef CONFIG_MD_BOOT        extern void md_setup_drive(void) __init;#endif#ifdef CONFIG_FC4_SOC	extern int soc_probe(void);#endif	struct gendisk *p;#ifdef CONFIG_PARPORT	parport_init();#endif	chr_dev_init();	blk_dev_init();	sti();#ifdef CONFIG_BLK_DEV_DAC960	DAC960_Initialize();#endif#ifdef CONFIG_FC4_SOC	/* This has to be done before scsi_dev_init */	soc_probe();#endif#ifdef CONFIG_SCSI	scsi_dev_init();#endif#ifdef CONFIG_BLK_CPQ_DA	cpqarray_init();#endif#ifdef CONFIG_INET	net_dev_init();#endif#ifdef CONFIG_VT	console_map_init();#endif	for (p = gendisk_head ; p ; p=p->next)		setup_dev(p);#ifdef CONFIG_BLK_DEV_RAM#ifdef CONFIG_BLK_DEV_INITRD	if (initrd_start && mount_initrd) initrd_load();	else#endif	rd_load();#endif#ifdef CONFIG_MD_BOOT        md_setup_drive();#endif}#ifdef CONFIG_PROC_FSint get_partition_list(char * page){	struct gendisk *p;	char buf[MAX_DISKNAME_LEN];	int n, len;	len = sprintf(page, "major minor  #blocks  name\n\n");	for (p = gendisk_head; p; p = p->next) {		for (n=0; n < (p->nr_real << p->minor_shift); n++) {			if (p->part[n].nr_sects && len < PAGE_SIZE - 80) {				len += sprintf(page+len,					       "%4d  %4d %10d %s\n",					       p->major, n, p->sizes[n],					       disk_name(p, n, buf));			}		}	}	return len;}#endif

⌨️ 快捷键说明

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