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

📄 memory.c

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

09700	/* This file contains the device dependent part of the drivers for the
09701	 * following special files:
09702	 *     /dev/null        - null device (data sink)
09703	 *     /dev/mem         - absolute memory
09704	 *     /dev/kmem        - kernel virtual memory
09705	 *     /dev/ram         - RAM disk
09706	 *
09707	 * The file contains one entry point:
09708	 *
09709	 *   mem_task:  main entry when system is brought up
09710	 *
09711	 *  Changes:
09712	 *      20 Apr  1992 by Kees J. Bot: device dependent/independent split
09713	 */
09714	
09715	#include "kernel.h"
09716	#include "driver.h"
09717	#include <sys/ioctl.h>
09718	
09719	#define NR_RAMS            4    /* number of RAM-type devices */
09720	
09721	PRIVATE struct device m_geom[NR_RAMS];  /* Base and size of each RAM disk */
09722	PRIVATE int m_device;           /* current device */
09723	
09724	FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
09725	FORWARD _PROTOTYPE( int m_schedule, (int proc_nr, struct iorequest_s *iop) );
09726	FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) );
09727	FORWARD _PROTOTYPE( void m_init, (void) );
09728	FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr) );
09729	FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
09730	
09731	
09732	/* Entry points to this driver. */
09733	PRIVATE struct driver m_dtab = {
09734	  no_name,      /* current device's name */
09735	  m_do_open,    /* open or mount */
09736	  do_nop,       /* nothing on a close */
09737	  m_ioctl,      /* specify ram disk geometry */
09738	  m_prepare,    /* prepare for I/O on a given minor device */
09739	  m_schedule,   /* do the I/O */
09740	  nop_finish,   /* schedule does the work, no need to be smart */
09741	  nop_cleanup,  /* nothing's dirty */
09742	  m_geometry,   /* memory device "geometry" */
09743	};
09744	
09745	
09746	/*===========================================================================*
09747	 *                              mem_task                                     *
09748	 *===========================================================================*/
09749	PUBLIC void mem_task()
09750	{
09751	  m_init();
09752	  driver_task(&m_dtab);
09753	}
	
	
09756	/*===========================================================================*
09757	 *                              m_prepare                                    *
09758	 *===========================================================================*/
09759	PRIVATE struct device *m_prepare(device)
09760	int device;
09761	{
09762	/* Prepare for I/O on a device. */
09763	
09764	  if (device < 0 || device >= NR_RAMS) return(NIL_DEV);
09765	  m_device = device;
09766	
09767	  return(&m_geom[device]);
09768	}
	
	
09771	/*===========================================================================*
09772	 *                              m_schedule                                   *
09773	 *===========================================================================*/
09774	PRIVATE int m_schedule(proc_nr, iop)
09775	int proc_nr;                    /* process doing the request */
09776	struct iorequest_s *iop;        /* pointer to read or write request */
09777	{
09778	/* Read or write /dev/null, /dev/mem, /dev/kmem, or /dev/ram. */
09779	
09780	  int device, count, opcode;
09781	  phys_bytes mem_phys, user_phys;
09782	  struct device *dv;
09783	
09784	  /* Type of request */
09785	  opcode = iop->io_request & ~OPTIONAL_IO;
09786	
09787	  /* Get minor device number and check for /dev/null. */
09788	  device = m_device;
09789	  dv = &m_geom[device];
09790	
09791	  /* Determine address where data is to go or to come from. */
09792	  user_phys = numap(proc_nr, (vir_bytes) iop->io_buf,
09793	                                                (vir_bytes) iop->io_nbytes);
09794	  if (user_phys == 0) return(iop->io_nbytes = EINVAL);
09795	
09796	  if (device == NULL_DEV) {
09797	        /* /dev/null: Black hole. */
09798	        if (opcode == DEV_WRITE) iop->io_nbytes = 0;
09799	        count = 0;
09800	  } else {
09801	        /* /dev/mem, /dev/kmem, or /dev/ram: Check for EOF */
09802	        if (iop->io_position >= dv->dv_size) return(OK);
09803	        count = iop->io_nbytes;
09804	        if (iop->io_position + count > dv->dv_size)
09805	                count = dv->dv_size - iop->io_position;
09806	  }
09807	
09808	  /* Set up 'mem_phys' for /dev/mem, /dev/kmem, or /dev/ram */
09809	  mem_phys = dv->dv_base + iop->io_position;
09810	
09811	  /* Book the number of bytes to be transferred in advance. */
09812	  iop->io_nbytes -= count;
09813	
09814	  if (count == 0) return(OK);
09815	
09816	  /* Copy the data. */
09817	  if (opcode == DEV_READ)
09818	        phys_copy(mem_phys, user_phys, (phys_bytes) count);
09819	  else
09820	        phys_copy(user_phys, mem_phys, (phys_bytes) count);
09821	
09822	  return(OK);
09823	}
	
	
09826	/*============================================================================*
09827	 *                              m_do_open                                     *
09828	 *============================================================================*/
09829	PRIVATE int m_do_open(dp, m_ptr)
09830	struct driver *dp;
09831	message *m_ptr;
09832	{
09833	/* Check device number on open.  Give I/O privileges to a process opening
09834	 * /dev/mem or /dev/kmem.
09835	 */
09836	
09837	  if (m_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO);
09838	
09839	  if (m_device == MEM_DEV || m_device == KMEM_DEV)
09840	        enable_iop(proc_addr(m_ptr->PROC_NR));
09841	
09842	  return(OK);
09843	}
	
	
09846	/*===========================================================================*
09847	 *                              m_init                                       *
09848	 *===========================================================================*/
09849	PRIVATE void m_init()
09850	{
09851	  /* Initialize this task. */
09852	  extern int _end;
09853	
09854	  m_geom[KMEM_DEV].dv_base = vir2phys(0);
09855	  m_geom[KMEM_DEV].dv_size = vir2phys(&_end);
09856	
09857	#if (CHIP == INTEL)
09858	  if (!protected_mode) {
09859	        m_geom[MEM_DEV].dv_size =   0x100000;   /* 1M for 8086 systems */
09860	  } else {
09861	#if _WORD_SIZE == 2
09862	        m_geom[MEM_DEV].dv_size =  0x1000000;   /* 16M for 286 systems */
09863	#else
09864	        m_geom[MEM_DEV].dv_size = 0xFFFFFFFF;   /* 4G-1 for 386 systems */
09865	#endif
09866	  }
09867	#endif
09868	}
	
	
09871	/*===========================================================================*
09872	 *                              m_ioctl                                      *
09873	 *===========================================================================*/
09874	PRIVATE int m_ioctl(dp, m_ptr)
09875	struct driver *dp;
09876	message *m_ptr;                 /* pointer to read or write message */
09877	{
09878	/* Set parameters for one of the RAM disks. */
09879	
09880	  unsigned long bytesize;
09881	  unsigned base, size;
09882	  struct memory *memp;
09883	  static struct psinfo psinfo = { NR_TASKS, NR_PROCS, (vir_bytes) proc, 0, 0 };
09884	  phys_bytes psinfo_phys;
09885	
09886	  switch (m_ptr->REQUEST) {
09887	  case MIOCRAMSIZE:
09888	        /* FS sets the RAM disk size. */
09889	        if (m_ptr->PROC_NR != FS_PROC_NR) return(EPERM);
09890	
09891	        bytesize = m_ptr->POSITION * BLOCK_SIZE;
09892	        size = (bytesize + CLICK_SHIFT-1) >> CLICK_SHIFT;
09893	
09894	        /* Find a memory chunk big enough for the RAM disk. */
09895	        memp= &mem[NR_MEMS];
09896	        while ((--memp)->size < size) {
09897	                if (memp == mem) panic("RAM disk is too big", NO_NUM);
09898	        }
09899	        base = memp->base;
09900	        memp->base += size;
09901	        memp->size -= size;
09902	
09903	        m_geom[RAM_DEV].dv_base = (unsigned long) base << CLICK_SHIFT;
09904	        m_geom[RAM_DEV].dv_size = bytesize;
09905	        break;
09906	  case MIOCSPSINFO:
09907	        /* MM or FS set the address of their process table. */
09908	        if (m_ptr->PROC_NR == MM_PROC_NR) {
09909	                psinfo.mproc = (vir_bytes) m_ptr->ADDRESS;
09910	        } else
09911	        if (m_ptr->PROC_NR == FS_PROC_NR) {
09912	                psinfo.fproc = (vir_bytes) m_ptr->ADDRESS;
09913	        } else {
09914	                return(EPERM);
09915	        }
09916	        break;
09917	  case MIOCGPSINFO:
09918	        /* The ps program wants the process table addresses. */
09919	        psinfo_phys = numap(m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS,
09920	                                                        sizeof(psinfo));
09921	        if (psinfo_phys == 0) return(EFAULT);
09922	        phys_copy(vir2phys(&psinfo), psinfo_phys, (phys_bytes) sizeof(psinfo));
09923	        break;
09924	  default:
09925	        return(do_diocntl(&m_dtab, m_ptr));
09926	  }
09927	  return(OK);
09928	}
	
	
09931	/*============================================================================*
09932	 *                              m_geometry                                    *
09933	 *============================================================================*/
09934	PRIVATE void m_geometry(entry)
09935	struct partition *entry;
09936	{
09937	  /* Memory devices don't have a geometry, but the outside world insists. */
09938	  entry->cylinders = (m_geom[m_device].dv_size >> SECTOR_SHIFT) / (64 * 32);
09939	  entry->heads = 64;
09940	  entry->sectors = 32;
09941	}

⌨️ 快捷键说明

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