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

📄 drvlib.c

📁 一个简单的操作系统minix的核心代码
💻 C
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				src/kernel/drvlib.c	 	 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

09500	/* IBM device driver utility functions.                 Author: Kees J. Bot
09501	 *                                                              7 Dec 1995
09502	 * Entry point:
09503	 *   partition: partition a disk to the partition table(s) on it.
09504	 */
09505	
09506	#include "kernel.h"
09507	#include "driver.h"
09508	#include "drvlib.h"
09509	
09510	
09511	FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
09512	                                                unsigned long extbase) );
09513	FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device,
09514	                        unsigned long offset, struct part_entry *table) );
09515	FORWARD _PROTOTYPE( void sort, (struct part_entry *table) );
09516	
09517	
09518	/*============================================================================*
09519	 *                              partition                                     *
09520	 *============================================================================*/
09521	PUBLIC void partition(dp, device, style)
09522	struct driver *dp;      /* device dependent entry points */
09523	int device;             /* device to partition */
09524	int style;              /* partitioning style: floppy, primary, sub. */
09525	{
09526	/* This routine is called on first open to initialize the partition tables
09527	 * of a device.  It makes sure that each partition falls safely within the
09528	 * device's limits.  Depending on the partition style we are either making
09529	 * floppy partitions, primary partitions or subpartitions.  Only primary
09530	 * partitions are sorted, because they are shared with other operating
09531	 * systems that expect this.
09532	 */
09533	  struct part_entry table[NR_PARTITIONS], *pe;
09534	  int disk, par;
09535	  struct device *dv;
09536	  unsigned long base, limit, part_limit;
09537	
09538	  /* Get the geometry of the device to partition */
09539	  if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV || dv->dv_size == 0) return;
09540	  base = dv->dv_base >> SECTOR_SHIFT;
09541	  limit = base + (dv->dv_size >> SECTOR_SHIFT);
09542	
09543	  /* Read the partition table for the device. */
09544	  if (!get_part_table(dp, device, 0L, table)) return;
09545	
09546	  /* Compute the device number of the first partition. */
09547	  switch (style) {
09548	  case P_FLOPPY:
09549	        device += MINOR_fd0a;
09550	        break;
09551	  case P_PRIMARY:
09552	        sort(table);            /* sort a primary partition table */
09553	        device += 1;
09554	        break;
09555	  case P_SUB:
09556	        disk = device / DEV_PER_DRIVE;
09557	        par = device % DEV_PER_DRIVE - 1;
09558	        device = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
09559	  }
09560	
09561	  /* Find an array of devices. */
09562	  if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV) return;
09563	
09564	  /* Set the geometry of the partitions from the partition table. */
09565	  for (par = 0; par < NR_PARTITIONS; par++, dv++) {
09566	        /* Shrink the partition to fit within the device. */
09567	        pe = &table[par];
09568	        part_limit = pe->lowsec + pe->size;
09569	        if (part_limit < pe->lowsec) part_limit = limit;
09570	        if (part_limit > limit) part_limit = limit;
09571	        if (pe->lowsec < base) pe->lowsec = base;
09572	        if (part_limit < pe->lowsec) part_limit = pe->lowsec;
09573	
09574	        dv->dv_base = pe->lowsec << SECTOR_SHIFT;
09575	        dv->dv_size = (part_limit - pe->lowsec) << SECTOR_SHIFT;
09576	
09577	        if (style == P_PRIMARY) {
09578	                /* Each Minix primary partition can be subpartitioned. */
09579	                if (pe->sysind == MINIX_PART)
09580	                        partition(dp, device + par, P_SUB);
09581	
09582	                /* An extended partition has logical partitions. */
09583	                if (pe->sysind == EXT_PART)
09584	                        extpartition(dp, device + par, pe->lowsec);
09585	        }
09586	  }
09587	}
	
	
09590	/*============================================================================*
09591	 *                              extpartition                                  *
09592	 *============================================================================*/
09593	PRIVATE void extpartition(dp, extdev, extbase)
09594	struct driver *dp;      /* device dependent entry points */
09595	int extdev;             /* extended partition to scan */
09596	unsigned long extbase;  /* sector offset of the base extended partition */
09597	{
09598	/* Extended partitions cannot be ignored alas, because people like to move
09599	 * files to and from DOS partitions.  Avoid reading this code, it's no fun.
09600	 */
09601	  struct part_entry table[NR_PARTITIONS], *pe;
09602	  int subdev, disk, par;
09603	  struct device *dv;
09604	  unsigned long offset, nextoffset;
09605	
09606	  disk = extdev / DEV_PER_DRIVE;
09607	  par = extdev % DEV_PER_DRIVE - 1;
09608	  subdev = MINOR_hd1a + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
09609	
09610	  offset = 0;
09611	  do {
09612	        if (!get_part_table(dp, extdev, offset, table)) return;
09613	        sort(table);
09614	
09615	        /* The table should contain one logical partition and optionally
09616	         * another extended partition.  (It's a linked list.)
09617	         */
09618	        nextoffset = 0;
09619	        for (par = 0; par < NR_PARTITIONS; par++) {
09620	                pe = &table[par];
09621	                if (pe->sysind == EXT_PART) {
09622	                        nextoffset = pe->lowsec;
09623	                } else
09624	                if (pe->sysind != NO_PART) {
09625	                        if ((dv = (*dp->dr_prepare)(subdev)) == NIL_DEV) return;
09626	
09627	                        dv->dv_base = (extbase + offset
09628	                                        + pe->lowsec) << SECTOR_SHIFT;
09629	                        dv->dv_size = pe->size << SECTOR_SHIFT;
09630	
09631	                        /* Out of devices? */
09632	                        if (++subdev % NR_PARTITIONS == 0) return;
09633	                }
09634	        }
09635	  } while ((offset = nextoffset) != 0);
09636	}
	
	
09639	/*============================================================================*
09640	 *                              get_part_table                                *
09641	 *============================================================================*/
09642	PRIVATE int get_part_table(dp, device, offset, table)
09643	struct driver *dp;
09644	int device;
09645	unsigned long offset;           /* sector offset to the table */
09646	struct part_entry *table;       /* four entries */
09647	{
09648	/* Read the partition table for the device, return true iff there were no
09649	 * errors.
09650	 */
09651	  message mess;
09652	
09653	  mess.DEVICE = device;
09654	  mess.POSITION = offset << SECTOR_SHIFT;
09655	  mess.COUNT = SECTOR_SIZE;
09656	  mess.ADDRESS = (char *) tmp_buf;
09657	  mess.PROC_NR = proc_number(proc_ptr);
09658	  mess.m_type = DEV_READ;
09659	
09660	  if (do_rdwt(dp, &mess) != SECTOR_SIZE) {
09661	        printf("%s: can't read partition table\n", (*dp->dr_name)());
09662	        return 0;
09663	  }
09664	  if (tmp_buf[510] != 0x55 || tmp_buf[511] != 0xAA) {
09665	        /* Invalid partition table. */
09666	        return 0;
09667	  }
09668	  memcpy(table, (tmp_buf + PART_TABLE_OFF), NR_PARTITIONS * sizeof(table[0]));
09669	  return 1;
09670	}
	
	
09673	/*===========================================================================*
09674	 *                              sort                                         *
09675	 *===========================================================================*/
09676	PRIVATE void sort(table)
09677	struct part_entry *table;
09678	{
09679	/* Sort a partition table. */
09680	  struct part_entry *pe, tmp;
09681	  int n = NR_PARTITIONS;
09682	
09683	  do {
09684	        for (pe = table; pe < table + NR_PARTITIONS-1; pe++) {
09685	                if (pe[0].sysind == NO_PART
09686	                        || (pe[0].lowsec > pe[1].lowsec
09687	                                        && pe[1].sysind != NO_PART)) {
09688	                        tmp = pe[0]; pe[0] = pe[1]; pe[1] = tmp;
09689	                }
09690	        }
09691	  } while (--n > 0);
09692	}

⌨️ 快捷键说明

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