亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? mem.c

?? Simple Operating Systems (簡稱SOS)是一個可以運行在X86平臺上(包括QEMU
?? C
字號:
/* Copyright (C) 2005 David Decotigny   This program is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public License   as published by the Free Software Foundation; either version 2   of the License, or (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,   USA. */#include <sos/assert.h>#include <sos/kmalloc.h>#include <sos/physmem.h>#include <hwcore/paging.h>#include <sos/kmem_slab.h>#include <sos/list.h>#include <hwcore/paging.h>#include <drivers/devices.h>#include <sos/kmem_vmm.h>#include <sos/uaccess.h>#include <sos/chardev.h>#include "mem.h"/** * A mapped mem/kmem resource */struct kernel_remapped_resource{  int ref_cnt;  struct sos_umem_vmm_mapped_resource mr;};/** Called after the virtual region has been inserted inside its    address space */static void resource_ref(struct sos_umem_vmm_vr * vr){  /* Retrieve the mem/kmem structure associated with the mapped resource */  struct kernel_remapped_resource * resource;  resource    = (struct kernel_remapped_resource*)    sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;  /* Increment ref counter */  resource->ref_cnt ++;}/** Called when the virtual region is removed from its address    space */static void resource_unref(struct sos_umem_vmm_vr * vr){  /* Retrieve the mem/kmem structure associated with the mapped resource */  struct kernel_remapped_resource * resource;  resource    = (struct kernel_remapped_resource*)    sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;    /* Decrement ref coutner */  SOS_ASSERT_FATAL(resource->ref_cnt > 0);  resource->ref_cnt --;  /* Free the resource if it becomes unused */  if (resource->ref_cnt == 0)    sos_kfree((sos_vaddr_t)resource);}/** MOST IMPORTANT callback ! Called when a thread page faults on the    resource's mapping */static sos_ret_t kmem_page_in(struct sos_umem_vmm_vr * vr,			      sos_uaddr_t uaddr,			      sos_bool_t write_access){  sos_vaddr_t vaddr;  sos_ret_t retval = SOS_OK;  sos_paddr_t ppage_paddr;  /* Compute address of kernel page */  vaddr = uaddr - sos_umem_vmm_get_start_of_vr(vr)    + sos_umem_vmm_get_offset_in_resource(vr);  /* Don't allow demand paging of non kernel pages */  if (vaddr >= SOS_PAGING_BASE_USER_ADDRESS)    return -SOS_EFAULT;  /* Lookup physical kernel page */  ppage_paddr = sos_paging_get_paddr(SOS_PAGE_ALIGN_INF(vaddr));  /* Cannot access unmapped kernel pages */  if (! ppage_paddr)    return -SOS_EFAULT;    /* Remap it in user space */  retval = sos_paging_map(ppage_paddr,			  SOS_PAGE_ALIGN_INF(uaddr),			  TRUE,			  sos_umem_vmm_get_prot_of_vr(vr));  return retval;}/** The callbacks for a mapped kmem resource */static struct sos_umem_vmm_vr_ops kmem_ops = (struct sos_umem_vmm_vr_ops){  .ref     = resource_ref,  .unref   = resource_unref,  .page_in = kmem_page_in,};/** The callback that gets called when the resource gets mapped */static sos_ret_t kmem_mmap(struct sos_umem_vmm_vr *vr){  return sos_umem_vmm_set_ops_of_vr(vr, &kmem_ops);}/** The function responsible for mapping the /dev/kmem resource in    user space */staticsos_ret_t sos_dev_kmem_map(struct sos_umem_vmm_as * dest_as,			   sos_uaddr_t *uaddr,			   sos_size_t size,			   sos_vaddr_t offset,			   sos_ui32_t access_rights,			   sos_ui32_t flags){  sos_ret_t retval;  struct kernel_remapped_resource * kmem_resource;  /* Allocate a new "descriptor" for the resource */  kmem_resource    = (struct kernel_remapped_resource*) sos_kmalloc(sizeof(*kmem_resource),						     0);  if (! kmem_resource)    return -SOS_ENOMEM;  memset(kmem_resource, 0x0, sizeof(*kmem_resource));  kmem_resource->mr.allowed_access_rights     = SOS_VM_MAP_PROT_READ    | SOS_VM_MAP_PROT_WRITE    | SOS_VM_MAP_PROT_EXEC;  kmem_resource->mr.custom_data    = kmem_resource;  kmem_resource->mr.mmap           = kmem_mmap;  /* Map it in user space */  retval = sos_umem_vmm_map(dest_as, uaddr, size,			    access_rights, flags,			    & kmem_resource->mr, offset);  if (SOS_OK != retval)    {      sos_kfree((sos_vaddr_t)kmem_resource);      return retval;    }  return SOS_OK;}/** MOST IMPORTANT callback ! Called when a thread page faults on the    resource's mapping */static sos_ret_t physmem_page_in(struct sos_umem_vmm_vr * vr,				 sos_uaddr_t uaddr,				 sos_bool_t write_access){  sos_ret_t retval = SOS_OK;  sos_paddr_t ppage_paddr;  /* Compute address of kernel page */  ppage_paddr = uaddr - sos_umem_vmm_get_start_of_vr(vr)    + sos_umem_vmm_get_offset_in_resource(vr);  /* Remap page in user space */  retval = sos_paging_map(SOS_PAGE_ALIGN_INF(ppage_paddr),			  SOS_PAGE_ALIGN_INF(uaddr),			  TRUE,			  sos_umem_vmm_get_prot_of_vr(vr));  return retval;}/** The callbacks for a mapped physmem resource */static struct sos_umem_vmm_vr_ops physmem_ops = (struct sos_umem_vmm_vr_ops){  .ref     = resource_ref,  .unref   = resource_unref,  .page_in = physmem_page_in,};/** The callback that gets called when the resource gets mapped */static sos_ret_t physmem_mmap(struct sos_umem_vmm_vr *vr){  return sos_umem_vmm_set_ops_of_vr(vr, &physmem_ops);}/** The function responsible for mapping the /dev/mem resource in    user space */staticsos_ret_t sos_dev_physmem_map(struct sos_umem_vmm_as * dest_as,			      sos_uaddr_t *uaddr,			      sos_size_t size,			      sos_paddr_t offset,			      sos_ui32_t access_rights,			      sos_ui32_t flags){  sos_ret_t retval;  struct kernel_remapped_resource * physmem_resource;  physmem_resource    = (struct kernel_remapped_resource*) sos_kmalloc(sizeof(*physmem_resource),						     0);  if (! physmem_resource)    return -SOS_ENOMEM;  memset(physmem_resource, 0x0, sizeof(*physmem_resource));  physmem_resource->mr.allowed_access_rights     = SOS_VM_MAP_PROT_READ    | SOS_VM_MAP_PROT_WRITE    | SOS_VM_MAP_PROT_EXEC;  physmem_resource->mr.custom_data    = physmem_resource;  physmem_resource->mr.mmap           = physmem_mmap;  retval = sos_umem_vmm_map(dest_as, uaddr, size,			    access_rights, flags,			    & physmem_resource->mr, offset);  if (SOS_OK != retval)    {      sos_kfree((sos_vaddr_t)physmem_resource);      return retval;    }  return SOS_OK;}/* * /dev/mem and /dev/kmem character device operations * * the "custom_data" field of the FS node is used to store the total * number of pages available */#define GET_DEV_SIZE(fsnode) \  ((sos_size_t)(fsnode)->custom_data)static sos_ret_t dev_mem_fs_open(struct sos_fs_node        * fsnode,				 struct sos_fs_opened_file * of,				 void * chardev_class_custom_data){  /* Make sure the device is supported by this driver and compute its     "size" (use the custom_data field to store it) */  switch (fsnode->dev_id.device_instance)    {      /* For /dev/kmem, go to the end of the kernel mapping */    case SOS_CHARDEV_KMEM_MINOR:      fsnode->custom_data = (void*)SOS_PAGING_BASE_USER_ADDRESS;      return SOS_OK;      break;      /* For /dev/mem, go to the end of physical memory */    case SOS_CHARDEV_PHYSMEM_MINOR:      {	sos_size_t ram_pages = 0;	sos_physmem_get_state(& ram_pages, NULL);	fsnode->custom_data = (void*)(ram_pages << SOS_PAGE_SHIFT);      }      return SOS_OK;      break;    default:      break;    }  return -SOS_ENODEV;}static sos_ret_t dev_mem_fs_seek(struct sos_fs_opened_file *this,				 sos_lsoffset_t offset,				 sos_seek_whence_t whence,				 /* out */ sos_lsoffset_t * result_position){  /* Make sure the device is supported by this driver */  struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(this->direntry);  /* Artificiallly update the position in the "file" */  sos_lsoffset_t ref_offs;  sos_lsoffset_t dev_size = GET_DEV_SIZE(fsnode);  *result_position = this->position;  switch (whence)    {    case SOS_SEEK_SET:      ref_offs = 0;      break;    case SOS_SEEK_CUR:      ref_offs = this->position;      break;    case SOS_SEEK_END:      ref_offs = dev_size;      break;    default:      return -SOS_EINVAL;    }  /* Forbid accesses "before" the start of the device */  if (offset < -ref_offs)    return -SOS_EINVAL;  /* Forbid accesses "after" the end of the device */  else if (ref_offs + offset > dev_size)    return -SOS_EINVAL;    this->position = ref_offs + offset;  *result_position = this->position;  return SOS_OK;}typedef enum { DO_READ, DO_WRITE } dev_mem_access_type_t;static sos_ret_t dev_mem_fs_access(struct sos_fs_opened_file *this,				   sos_uaddr_t user_buf,				   sos_size_t * /* in/out */len,				   dev_mem_access_type_t access_type){  struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(this->direntry);  sos_vaddr_t   physmem_transfer_kernel_page = 0; /* Used for /dev/mem only */  sos_uoffset_t offs;  sos_size_t    accesslen = 0;  /* Readjust copy length to match the size of the device */  if (this->position + *len >= GET_DEV_SIZE(fsnode))    *len = GET_DEV_SIZE(fsnode) - this->position;  /* Ignore zero-size requests */  if (*len <= 0)    return SOS_OK;  /* For /dev/mem device, prepare a kernel page to copy the physical     pages before transferring to user space */  if (SOS_CHARDEV_PHYSMEM_MINOR == fsnode->dev_id.device_instance)    {      physmem_transfer_kernel_page = sos_kmem_vmm_alloc(1, 0);      if (! physmem_transfer_kernel_page)	return -SOS_ENOMEM;    }  /* Try to copy the data in page-size chunks */  offs = this->position;  while (offs < this->position + *len)    {      /* Retrieve page address of data in kernel memory */      sos_uoffset_t page_boundary = SOS_PAGE_ALIGN_INF(offs);      sos_vaddr_t   page_vaddr;      sos_uoffset_t offset_in_page;      sos_uoffset_t accesslen_in_page;      sos_ret_t retval;      /* For /dev/mem device, we need to map the page in kernel memory	 before */      if (SOS_CHARDEV_PHYSMEM_MINOR == fsnode->dev_id.device_instance)	{	  retval = sos_paging_map(page_boundary,				  physmem_transfer_kernel_page,				  FALSE,				  (access_type==DO_WRITE)?				    SOS_VM_MAP_PROT_WRITE				    :SOS_VM_MAP_PROT_READ);	  if (SOS_OK != retval)	    break;	  page_vaddr = physmem_transfer_kernel_page;	}      /* For /dev/kmem device, the page should already be in kernel space */      else if (! sos_kmem_vmm_is_valid_vaddr(page_boundary))	break; /* No: page is not mapped in kernel space ! */      else	page_vaddr = page_boundary; /* Yes, page is mapped */      /* Now copy the data from kernel to user space */      offset_in_page = offs - page_boundary;      accesslen_in_page  = SOS_PAGE_SIZE - offset_in_page;      if (accesslen + accesslen_in_page > *len)	accesslen_in_page = *len - accesslen;      if (access_type==DO_WRITE)	retval = sos_memcpy_from_user(page_vaddr + offset_in_page,				      user_buf + accesslen,				      accesslen_in_page);      else	retval = sos_memcpy_to_user(user_buf + accesslen,				    page_vaddr + offset_in_page,				    accesslen_in_page);            /* Now, for /dev/mem, unmap the page from kernel */      if (SOS_CHARDEV_PHYSMEM_MINOR == fsnode->dev_id.device_instance)	sos_paging_unmap(physmem_transfer_kernel_page);            /* Go to next page if possible */      if (retval < 0)	break;      accesslen += retval;      /* If transfer was interrupted, stop here */      if (retval < accesslen_in_page)	break;      /* Go on to next page */      offs = page_boundary + SOS_PAGE_SIZE;    }  /* Release the temporary page for physical mem transfers */  if (SOS_CHARDEV_PHYSMEM_MINOR == fsnode->dev_id.device_instance)    sos_kmem_vmm_free(physmem_transfer_kernel_page);  /* Update the position in the "file" */  *len = accesslen;  this->position += accesslen;  return SOS_OK;}static sos_ret_t dev_mem_fs_read(struct sos_fs_opened_file *this,				   sos_uaddr_t dest_buf,				   sos_size_t * /* in/out */len){  return dev_mem_fs_access(this, dest_buf, len, DO_READ);}static sos_ret_t dev_mem_fs_write(struct sos_fs_opened_file *this,				  sos_uaddr_t src_buf,				  sos_size_t * /* in/out */len){  return dev_mem_fs_access(this, src_buf, len, DO_WRITE);}static sos_ret_t dev_mem_fs_mmap(struct sos_fs_opened_file *this,				 sos_uaddr_t *uaddr, sos_size_t size,				 sos_ui32_t access_rights,				 sos_ui32_t flags,				 sos_luoffset_t offset){  struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(this->direntry);  if (SOS_CHARDEV_PHYSMEM_MINOR == fsnode->dev_id.device_instance)    return sos_dev_physmem_map(sos_process_get_address_space(this->owner),			       uaddr, size, offset, access_rights, flags);  return sos_dev_kmem_map(sos_process_get_address_space(this->owner),			  uaddr, size, offset, access_rights, flags);}static struct sos_chardev_ops dev_mem_fs_ops  = (struct sos_chardev_ops) {    .open  = dev_mem_fs_open,    .close = NULL,    .seek  = dev_mem_fs_seek,    .read  = dev_mem_fs_read,    .write = dev_mem_fs_write,    .mmap  = dev_mem_fs_mmap,    .fcntl = NULL,    .ioctl = NULL  };sos_ret_t sos_dev_mem_chardev_setup(){  return sos_chardev_register_class(SOS_CHARDEV_MEM_MAJOR,				    & dev_mem_fs_ops,				    NULL);}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
播五月开心婷婷综合| 国产精品一二三| 国产欧美日韩不卡免费| 日本久久电影网| 国产一区二区福利视频| 午夜精品免费在线| 欧美激情一区二区三区全黄| 欧美日韩高清一区二区三区| 99久久精品免费观看| 韩国毛片一区二区三区| 亚洲不卡av一区二区三区| 亚洲欧洲色图综合| 久久久久国产免费免费| 日韩免费观看高清完整版| 欧美在线观看视频一区二区 | 亚洲国产日韩精品| 中国av一区二区三区| 欧美xxxxxxxxx| 欧美一区二区女人| 欧美剧在线免费观看网站| 91麻豆蜜桃一区二区三区| 国产成人在线影院 | 国产不卡视频在线播放| 久久99国产精品免费网站| 视频一区二区三区中文字幕| 亚洲精品中文字幕在线观看| |精品福利一区二区三区| 国产欧美日韩不卡免费| 久久蜜桃一区二区| 亚洲精品一区二区三区99| 欧美一区二区精品在线| 欧美精品自拍偷拍动漫精品| 欧美视频一区在线观看| 欧美亚洲综合另类| 欧美日韩精品一区二区天天拍小说 | 91精品国产91久久久久久一区二区| 一本大道久久a久久综合婷婷| 97久久久精品综合88久久| 丰满少妇在线播放bd日韩电影| 国产一区二区三区久久悠悠色av| 久久黄色级2电影| 久久国产精品99精品国产 | 亚洲国产成人av好男人在线观看| 一区二区在线电影| 夜夜嗨av一区二区三区网页| 亚洲综合在线五月| 亚洲3atv精品一区二区三区| 日本aⅴ亚洲精品中文乱码| 免费成人av资源网| 国产一区在线视频| 国产91丝袜在线播放0| 国产三级精品视频| 国产精品素人一区二区| 自拍偷拍国产亚洲| 午夜av一区二区| 久久国产尿小便嘘嘘尿| 岛国一区二区三区| 99国产麻豆精品| 欧美视频一区二区三区在线观看 | 欧美午夜精品电影| 4438x亚洲最大成人网| 欧美成人福利视频| 国产精品三级电影| 亚洲第一精品在线| 国内精品久久久久影院薰衣草| 国产a精品视频| 色婷婷综合久久久中文一区二区 | 色综合亚洲欧洲| 欧美日韩亚洲综合在线| 日韩精品一区在线观看| 亚洲欧洲精品一区二区三区| 亚洲电影激情视频网站| 国产毛片一区二区| 日本精品视频一区二区三区| 制服丝袜亚洲播放| 国产亚洲综合性久久久影院| 尤物视频一区二区| 老色鬼精品视频在线观看播放| 国产99精品视频| 欧美精品18+| 国产精品久久久久毛片软件| 日韩在线观看一区二区| 国产精品99久久久久久似苏梦涵| 色综合久久综合| 亚洲精品一线二线三线| 亚洲国产欧美在线| 成人一区二区三区视频在线观看| 欧美日韩一级大片网址| 国产偷国产偷精品高清尤物| 亚洲一级二级在线| 懂色av中文字幕一区二区三区| 欧美日韩亚洲丝袜制服| 国产精品女人毛片| 青青草国产成人av片免费| 99久免费精品视频在线观看| 欧美一级xxx| 一区2区3区在线看| 成人av免费在线| 欧美精品一区二区三区蜜臀| 亚洲国产欧美一区二区三区丁香婷| 国产一区二区三区不卡在线观看| 欧美亚洲日本一区| 亚洲欧美在线观看| 国产在线播放一区三区四| 欧美日韩国产a| 一区二区在线看| 99久久精品久久久久久清纯| 精品国产露脸精彩对白| 亚洲成人免费视| 色偷偷久久人人79超碰人人澡| 国产亚洲综合在线| 激情文学综合丁香| 欧美一区二区在线观看| 亚洲va欧美va国产va天堂影院| 国产精品久久久久一区| 国内外精品视频| 在线播放日韩导航| 亚洲精品亚洲人成人网在线播放| 懂色av噜噜一区二区三区av| 久久亚洲精精品中文字幕早川悠里| 亚洲国产欧美在线| 欧洲激情一区二区| 亚洲精品免费播放| 日本精品视频一区二区| 亚洲同性同志一二三专区| av一二三不卡影片| 中文字幕制服丝袜一区二区三区 | 麻豆免费精品视频| 欧美日韩精品一区视频| 亚洲第一激情av| 欧美日本一道本在线视频| 亚洲高清不卡在线| 欧美三日本三级三级在线播放| 亚洲精品久久久蜜桃| 日本高清免费不卡视频| 一二三区精品福利视频| 欧美日韩视频在线一区二区| 亚洲一区二区三区中文字幕在线| 日本韩国视频一区二区| 亚洲一区二区成人在线观看| 欧美在线你懂得| 日日夜夜一区二区| 日韩视频一区二区三区在线播放| 麻豆中文一区二区| 久久久www成人免费无遮挡大片| 国产一区二区三区不卡在线观看| 国产日产精品一区| 成人18视频在线播放| 亚洲色图在线看| 欧美主播一区二区三区| 五月综合激情网| 精品少妇一区二区三区在线视频| 国产麻豆精品在线观看| 中文字幕综合网| 欧美日韩黄色一区二区| 蜜臀av在线播放一区二区三区| 久久嫩草精品久久久精品| 成人久久久精品乱码一区二区三区 | 在线不卡的av| 久久国产日韩欧美精品| 国产精品蜜臀av| 91久久精品一区二区三区| 人人超碰91尤物精品国产| 精品久久久网站| 91在线观看下载| 日日夜夜一区二区| 国产欧美精品一区| 91精彩视频在线观看| 免费在线一区观看| 久久精品视频免费| 色噜噜狠狠色综合欧洲selulu| 免费在线观看一区| 国产精品久久毛片a| 欧美精品第1页| 成人激情午夜影院| 三级在线观看一区二区| 欧美极品xxx| 欧美日韩国产一级| 成人黄色网址在线观看| 宅男噜噜噜66一区二区66| 国产精品一二三四五| 亚洲午夜日本在线观看| 精品嫩草影院久久| 色素色在线综合| 国产精品一区二区三区网站| 亚洲一区日韩精品中文字幕| 久久久久高清精品| 欧美私模裸体表演在线观看| 国产成人av自拍| 天天影视涩香欲综合网 | 一区二区三区四区蜜桃| 日韩欧美色综合网站| 91福利资源站| 成人avav在线| 日本三级亚洲精品| 亚洲欧美日韩国产综合| 精品999久久久| 7777女厕盗摄久久久| 91丨porny丨在线| 国产一级精品在线|