<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【原】獲取物理地址空間驅動

      獲取物理地址空間驅動,支持多個子驅動,Example: insmod gphyaddr.ko varm=1:4M,2:5K。

      #include <linux/module.h>
      #include <linux/kernel.h>
      #include <linux/fs.h>
      #include <linux/cdev.h>
      #include <linux/slab.h>
      
      #define    MAX_DEV_NUM             32
      #define    GET_PYH_SPACE_SIZE      0
      #define    GET_PYHSICAL_ADDR       1
      
      struct gphyaddr_dev
      {
          int dev_num;
          dev_t dev;
          struct class *cls;
          struct cdev cdev;
          
          int index[MAX_DEV_NUM];
          unsigned long space_size[MAX_DEV_NUM];
          
          unsigned int p_addr[MAX_DEV_NUM];
          unsigned int order[MAX_DEV_NUM];
          unsigned long v_addr[MAX_DEV_NUM];
      };
      
      static struct gphyaddr_dev * g_dev = NULL;
      static char * vram="1:4M";
      
      module_param(vram, charp, 0644);
      MODULE_PARM_DESC(vram,"A string variable");
      
      static int gphyaddr_open(struct inode *inode, struct file *file)
      {
          struct gphyaddr_dev * dev;
          dev = container_of(inode->i_cdev, struct gphyaddr_dev, cdev);
          
          file->private_data = dev;
          
          return 0;
      }
      
      static long gphyaddr_ioctl(struct file *file,
                              unsigned int cmd,
                              unsigned long arg)
      {
          struct gphyaddr_dev * dev = file->private_data;
          struct inode *inode = file->f_path.dentry->d_inode;
          
          int minor = MINOR(inode->i_rdev);
          //printk("%s:minor: %d.\n", __func__, minor);
          //printk("p_addr: 0x%x.\n", dev->p_addr[minor]);
          //printk("v_addr: 0x%lx, order: %d.\n", dev->v_addr[minor], dev->order[minor]);
      
          switch (cmd)
          {
              case GET_PYH_SPACE_SIZE:
                  return (long)(dev->order[minor] * PAGE_SIZE);
              case GET_PYHSICAL_ADDR:
                  return (long)dev->v_addr[minor];
              default:
                  printk("Parameter error!!\n");
                  return -1;
          }
          return 0;
      
      }
      
      struct file_operations gphyaddr_fops = {
          .owner =    THIS_MODULE,
          .open =     gphyaddr_open,
          .unlocked_ioctl = gphyaddr_ioctl,
      };
      
      static void gphyaddr_exit(void)
      {
          int index, i;
          
          printk("gphyaddr_exit.\n");
          if (g_dev)
          {
              for(i = 0; i < g_dev->dev_num; i++)
              {
                  index = g_dev->index[i];
                  device_destroy(g_dev->cls, MKDEV(MAJOR(g_dev->dev), index));
      
                  if(g_dev->v_addr[index] > 0)
                  {
                      free_pages(g_dev->v_addr[index], g_dev->order[index]);
                  }
              }
              if(NULL != g_dev->cls)
              {
                  class_destroy(g_dev->cls);
              }
              
              if(g_dev->cdev.count > 0)
              {
                  cdev_del(&g_dev->cdev);
              }
      
              if(g_dev->dev_num > 0)
              {
                  unregister_chrdev_region(g_dev->dev, g_dev->dev_num);
              }
              
              kfree(g_dev);
          }
      }
      
      static int get_phy_addr(struct gphyaddr_dev * g_dev, unsigned int space_size, int index)
      {
          char *v_addr;
          unsigned int p_addr,order;
          
          order = get_order(space_size);
          if(order >= MAX_ORDER)
          {
              printk("ERROR: order(%u) >= MAX_ORDER(%u)!!!\n", order, MAX_ORDER);
              order = MAX_ORDER - 1;
          }
          v_addr = (char *)__get_free_pages(GFP_KERNEL, order);
          if(v_addr == NULL)
          {
              printk("ERROR: get_free_pages err!!!\n");
              return -EFAULT;
          }
          
          p_addr = virt_to_phys(v_addr);
          
          printk("index= %d, order= %d, space_size= 0x%lx, p_addr: 0x%x\n", index, order, order * PAGE_SIZE, p_addr);
      
          g_dev->p_addr[index] = p_addr;
          g_dev->order[index] = order;
          g_dev->v_addr[index] = (unsigned long)v_addr;
      
          return 0;
      }
      
      static int parse_vram_param(struct gphyaddr_dev * g_dev, const char *param, int max_dev_num)
      {
          int i = 0;
          unsigned long size;
          char *p, *start;
      
          start = (char *)param;
          g_dev->dev_num = 0;
          
          while (1)
          {
              p = start;
      
              g_dev->index[i] = simple_strtoul(p, &p, 10);
      
              if (p == param)
                  goto err;
      
              if (*p != ':')
                  goto err;
      
              if (g_dev->index[i] > max_dev_num)
                  goto err;
      
              size = memparse(p + 1, &p);
      
              if (!size)
                  goto err;
              
              printk("i: %d index: %d size: 0x%x\n",i, g_dev->index[i], (u32)size);
              g_dev->space_size[g_dev->index[i]] = size;
              g_dev->dev_num++;
              i++;
      
              if (*p == 0)
                  break;
      
              if (*p != ',')
                  goto err;
      
              ++p;
      
              start = p;
          }
          
          return 0;
      err:
          printk("Input format error!!\n   Example: insmod gphyaddr.ko varm=1:4M,2:5K\n");
          return -EINVAL;
      }
      
      static int gphyaddr_init(void)
      {
          int ret, index, i;
          
          g_dev = kmalloc(sizeof(struct gphyaddr_dev), GFP_KERNEL);
          if (!g_dev)
          {
              printk("Error: kmalloc ERR.\n");
              ret = -ENOMEM;
              goto fail;
          }
          memset(g_dev, 0, sizeof(struct gphyaddr_dev));
      
          if (parse_vram_param(g_dev, vram, MAX_DEV_NUM))
           {
               printk("Error: failed to parse vram parameters: %s\n", vram);
               ret = -ENOMEM;
               goto fail;
           }
          
          alloc_chrdev_region(&g_dev->dev, 0, g_dev->dev_num, "gphyaddr");
          
          cdev_init(&g_dev->cdev, &gphyaddr_fops);
          g_dev->cdev.owner = THIS_MODULE;
          g_dev->cdev.ops = &gphyaddr_fops;
          ret = cdev_add (&g_dev->cdev, g_dev->dev, g_dev->dev_num);//添加字符設備
          if(ret)
          {
              printk("Error: %d adding gphyaddr.\n", ret);
              goto fail;
          }
          
          g_dev->cls = class_create(THIS_MODULE, "gphyaddr");
      
          for(i = 0; i < g_dev->dev_num; i++)
          {
              index = g_dev->index[i];
              ret = get_phy_addr(g_dev, g_dev->space_size[index], index);
              if(ret)
              {
                  printk("Error: %d get_phy_addr!!\n", ret);
                  goto fail;
              }
              
              device_create(g_dev->cls, NULL, MKDEV(MAJOR(g_dev->dev), index), NULL, "gphyaddr%d", index);
          }
          
          return 0;
          
      fail:
          gphyaddr_exit();
          return ret;
      }  
      
      module_init(gphyaddr_init);
      module_exit(gphyaddr_exit);
      MODULE_LICENSE("GPL");
      posted @ 2019-09-19 10:14  菜鳥升級  閱讀(446)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 在线观看成人av天堂不卡| 日韩一欧美内射在线观看| 盈江县| gogogo高清在线观看视频中文| 国产一卡2卡3卡4卡网站精品| 柳州市| 国产a在视频线精品视频下载| 国产一区二区高清不卡| 九九久久人妻精品一区色| 国产精品天堂蜜av在线播放| 亚洲精品久久无码av片软件| 色偷偷久久一区二区三区| 东方四虎av在线观看| 国产极品丝尤物在线观看| 中文字幕国产日韩精品| 国产在线超清日本一本| 欧美丰满熟妇性xxxx| 欧美性69式xxxx护士| 亚洲狠狠婷婷综合久久久| 巨胸不知火舞露双奶头无遮挡| 亚洲中文字幕一区精品自| 午夜免费无码福利视频麻豆| 樱花草在线社区WWW韩国| 国产不卡一区二区在线视频| 色综合视频一区二区三区| av永久免费网站在线观看| 兴文县| 国产999精品2卡3卡4卡| 久久这里有精品国产电影网| 亚洲欧美日韩精品久久| 97久久久亚洲综合久久| 亚洲午夜激情久久加勒比| 国产愉拍91九色国产愉拍| 久久这里都是精品一区| 最新偷拍一区二区三区| 亚洲 欧美 综合 另类 中字| 亚洲人成网站在线播放2019| 91在线国内在线播放老师| 国产精品视频亚洲二区| 韩国深夜福利视频在线观看| 高级艳妇交换俱乐部小说|