예제 #1
0
파일: ds.c 프로젝트: DragonQuan/minix3
int ds_retrieve_map(const char *ds_name, char *vaddr, size_t *length,
		int nr_snapshot, int flags)
{
	cp_grant_id_t gid;
	int r;

	/* Map a mapped memory range. */
	if(flags & DSMF_MAP_MAPPED) {
		/* Request DS to grant. */
		m.DS_FLAGS = DSF_TYPE_MAP | DSMF_MAP_MAPPED;
		r = do_invoke_ds(DS_RETRIEVE, ds_name);
		if(r != OK)
			return r;

		/* Do the safemap. */
		if(*length > (size_t) m.DS_VAL_LEN)
			*length = (size_t) m.DS_VAL_LEN;
		*length = (size_t) CLICK_FLOOR(*length);
		r = sys_safemap(DS_PROC_NR, m.DS_VAL, 0,
				(vir_bytes)vaddr, *length, D, 0);

	/* Copy mapped memory range or a snapshot. */
	} else if(flags & (DSMF_COPY_MAPPED|DSMF_COPY_SNAPSHOT)) {
		/* Grant for memory range first. */
		gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr,
				*length, CPF_WRITE);
		if(!GRANT_VALID(gid))
			return errno;

		m.DS_VAL = gid;
		m.DS_VAL_LEN = *length;
		if(flags & DSMF_COPY_MAPPED) {
			m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_MAPPED;
		}
		else {
			m.DS_NR_SNAPSHOT = nr_snapshot;
			m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_SNAPSHOT;
		}
		r = do_invoke_ds(DS_RETRIEVE, ds_name);
		*length = m.DS_VAL_LEN;
		cpf_revoke(gid);
	}
	else {
		return EINVAL;
	}

	return r;
}
/*===========================================================================*
 *                              get_mem_chunks                               *
 *===========================================================================*/
void get_mem_chunks(
struct memory *mem_chunks)                      /* store mem chunks here */ 
{  
/* Initialize the free memory list from the kernel-provided memory map.  Translate
 * the byte offsets and sizes in this list to clicks, properly truncated.
 */
  phys_bytes base, size, limit;
  int i;
  struct memory *memp;

  /* Initialize everything to zero. */
  memset(mem_chunks, 0, NR_MEMS*sizeof(*mem_chunks));

  /* Obtain and parse memory from kernel environment. */
  /* XXX Any memory chunk in excess of NR_MEMS is silently ignored. */
  for(i = 0; i < MIN(MAXMEMMAP, NR_MEMS); i++) {
  	mem_chunks[i].base = kernel_boot_info.memmap[i].mm_base_addr;
  	mem_chunks[i].size = kernel_boot_info.memmap[i].mm_length;
  }

  /* Round physical memory to clicks. Round start up, round end down. */
  for (i = 0; i < NR_MEMS; i++) {
        memp = &mem_chunks[i];          /* next mem chunk is stored here */
        base = mem_chunks[i].base;
        size = mem_chunks[i].size;
        limit = base + size;
        base = (phys_bytes) (CLICK_CEIL(base));
        limit = (phys_bytes) (CLICK_FLOOR(limit));
        if (limit <= base) {
                memp->base = memp->size = 0;
        } else { 
                memp->base = base >> CLICK_SHIFT;
                memp->size = (limit - base) >> CLICK_SHIFT;
        }
  }
}