当前位置: 首页 > news >正文

东莞网站开发建设网站建设1993seo

东莞网站开发建设,网站建设1993seo,广州网站建设有哪些,百度集团总部在哪里接前一篇文章#xff1a;QEMU源码全解析 —— virtio#xff08;21#xff09; 前几回讲解了virtio驱动的加载。本回开始讲解virtio驱动的初始化。 在讲解virtio驱动的初始化之前#xff0c;先要介绍virtio配置的函数集合变量virtio_pci_config_ops。实际上前文书也有提到…接前一篇文章QEMU源码全解析 —— virtio21 前几回讲解了virtio驱动的加载。本回开始讲解virtio驱动的初始化。 在讲解virtio驱动的初始化之前先要介绍virtio配置的函数集合变量virtio_pci_config_ops。实际上前文书也有提到如下图的右上角 virtio_pci_config_ops的初始化有两处分别在Linux内核源码/drivers/virtio/virtio_pci_legacy.c和Linux内核源码/drivers/virtio/virtio_pci_modern.c中。代码分别如下 legacy static const struct virtio_config_ops virtio_pci_config_ops {.get vp_get,.set vp_set,.get_status vp_get_status,.set_status vp_set_status,.reset vp_reset,.find_vqs vp_find_vqs,.del_vqs vp_del_vqs,.synchronize_cbs vp_synchronize_vectors,.get_features vp_get_features,.finalize_features vp_finalize_features,.bus_name vp_bus_name,.set_vq_affinity vp_set_vq_affinity,.get_vq_affinity vp_get_vq_affinity, }; modern static const struct virtio_config_ops virtio_pci_config_ops {.get vp_get,.set vp_set,.generation vp_generation,.get_status vp_get_status,.set_status vp_set_status,.reset vp_reset,.find_vqs vp_modern_find_vqs,.del_vqs vp_del_vqs,.synchronize_cbs vp_synchronize_vectors,.get_features vp_get_features,.finalize_features vp_finalize_features,.bus_name vp_bus_name,.set_vq_affinity vp_set_vq_affinity,.get_vq_affinity vp_get_vq_affinity,.get_shm_region vp_get_shm_region,.disable_vq_and_reset vp_modern_disable_vq_and_reset,.enable_vq_after_reset vp_modern_enable_vq_after_reset, }; 在此以Linux内核源码/drivers/virtio/virtio_pci_modern.c中的virtio_pci_config_ops为例进行讲解。 在前文书讲到的virtio_pci_modern_probe函数Linux内核源码/drivers/virtio/virtio_pci_modern.c中 /* the PCI probing function */ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev) {struct virtio_pci_modern_device *mdev vp_dev-mdev;struct pci_dev *pci_dev vp_dev-pci_dev;int err;mdev-pci_dev pci_dev;err vp_modern_probe(mdev);if (err)return err;if (mdev-device)vp_dev-vdev.config virtio_pci_config_ops;elsevp_dev-vdev.config virtio_pci_config_nodev_ops;vp_dev-config_vector vp_config_vector;vp_dev-setup_vq setup_vq;vp_dev-del_vq del_vq;vp_dev-isr mdev-isr;vp_dev-vdev.id mdev-id;return 0; } virtio_pci_config_ops变量被赋值给了virtio_device结构的config成员。struct virtio_device的定义在Linux内核源码/include/linux/virtio.h中代码如下 /*** struct virtio_device - representation of a device using virtio* index: unique position on the virtio bus* failed: saved value for VIRTIO_CONFIG_S_FAILED bit (for restore)* config_enabled: configuration change reporting enabled* config_change_pending: configuration change reported while disabled* config_lock: protects configuration change reporting* vqs_list_lock: protects vqs.* dev: underlying device.* id: the device type identification (used to match it with a driver).* config: the configuration ops for this device.* vringh_config: configuration ops for host vrings.* vqs: the list of virtqueues for this device.* features: the features supported by both driver and device.* priv: private pointer for the drivers use.*/ struct virtio_device {int index;bool failed;bool config_enabled;bool config_change_pending;spinlock_t config_lock;spinlock_t vqs_list_lock;struct device dev;struct virtio_device_id id;const struct virtio_config_ops *config;const struct vringh_config_ops *vringh_config;struct list_head vqs;u64 features;void *priv; }; 其中的struct virtio_config_ops的定义在Linux内核源码/include/linux/virtio_config.h中代码如下 /*** struct virtio_config_ops - operations for configuring a virtio device* Note: Do not assume that a transport implements all of the operations* getting/setting a value as a simple read/write! Generally speaking,* any of get/set, get_status/set_status, or get_features/* finalize_features are NOT safe to be called from an atomic* context.* get: read the value of a configuration field* vdev: the virtio_device* offset: the offset of the configuration field* buf: the buffer to write the field value into.* len: the length of the buffer* set: write the value of a configuration field* vdev: the virtio_device* offset: the offset of the configuration field* buf: the buffer to read the field value from.* len: the length of the buffer* generation: config generation counter (optional)* vdev: the virtio_device* Returns the config generation counter* get_status: read the status byte* vdev: the virtio_device* Returns the status byte* set_status: write the status byte* vdev: the virtio_device* status: the new status byte* reset: reset the device* vdev: the virtio device* After this, status and feature negotiation must be done again* Device must not be reset from its vq/config callbacks, or in* parallel with being added/removed.* find_vqs: find virtqueues and instantiate them.* vdev: the virtio_device* nvqs: the number of virtqueues to find* vqs: on success, includes new virtqueues* callbacks: array of callbacks, for each virtqueue* include a NULL entry for vqs that do not need a callback* names: array of virtqueue names (mainly for debugging)* include a NULL entry for vqs unused by driver* Returns 0 on success or error status* del_vqs: free virtqueues found by find_vqs().* synchronize_cbs: synchronize with the virtqueue callbacks (optional)* The function guarantees that all memory operations on the* queue before it are visible to the vring_interrupt() that is* called after it.* vdev: the virtio_device* get_features: get the array of feature bits for this device.* vdev: the virtio_device* Returns the first 64 feature bits (all we currently need).* finalize_features: confirm what device features well be using.* vdev: the virtio_device* This sends the driver feature bits to the device: it can change* the dev-feature bits if it wants.* Note that despite the name this can be called any number of* times.* Returns 0 on success or error status* bus_name: return the bus name associated with the device (optional)* vdev: the virtio_device* This returns a pointer to the bus name a la pci_name from which* the caller can then copy.* set_vq_affinity: set the affinity for a virtqueue (optional).* get_vq_affinity: get the affinity for a virtqueue (optional).* get_shm_region: get a shared memory region based on the index.* disable_vq_and_reset: reset a queue individually (optional).* vq: the virtqueue* Returns 0 on success or error status* disable_vq_and_reset will guarantee that the callbacks are disabled and* synchronized.* Except for the callback, the caller should guarantee that the vring is* not accessed by any functions of virtqueue.* enable_vq_after_reset: enable a reset queue* vq: the virtqueue* Returns 0 on success or error status* If disable_vq_and_reset is set, then enable_vq_after_reset must also be* set.*/ struct virtio_config_ops {void (*get)(struct virtio_device *vdev, unsigned offset,void *buf, unsigned len);void (*set)(struct virtio_device *vdev, unsigned offset,const void *buf, unsigned len);u32 (*generation)(struct virtio_device *vdev);u8 (*get_status)(struct virtio_device *vdev);void (*set_status)(struct virtio_device *vdev, u8 status);void (*reset)(struct virtio_device *vdev);int (*find_vqs)(struct virtio_device *, unsigned nvqs,struct virtqueue *vqs[], vq_callback_t *callbacks[],const char * const names[], const bool *ctx,struct irq_affinity *desc);void (*del_vqs)(struct virtio_device *);void (*synchronize_cbs)(struct virtio_device *);u64 (*get_features)(struct virtio_device *vdev);int (*finalize_features)(struct virtio_device *vdev);const char *(*bus_name)(struct virtio_device *vdev);int (*set_vq_affinity)(struct virtqueue *vq,const struct cpumask *cpu_mask);const struct cpumask *(*get_vq_affinity)(struct virtio_device *vdev,int index);bool (*get_shm_region)(struct virtio_device *vdev,struct virtio_shm_region *region, u8 id);int (*disable_vq_and_reset)(struct virtqueue *vq);int (*enable_vq_after_reset)(struct virtqueue *vq); }; 再回过头来看一下Linux内核源码/drivers/virtio/virtio_pci_modern.c中的virtio_pci_config_ops对照着上边 struct virtio_config_ops的定义。 static const struct virtio_config_ops virtio_pci_config_ops {.get vp_get,.set vp_set,.generation vp_generation,.get_status vp_get_status,.set_status vp_set_status,.reset vp_reset,.find_vqs vp_modern_find_vqs,.del_vqs vp_del_vqs,.synchronize_cbs vp_synchronize_vectors,.get_features vp_get_features,.finalize_features vp_finalize_features,.bus_name vp_bus_name,.set_vq_affinity vp_set_vq_affinity,.get_vq_affinity vp_get_vq_affinity,.get_shm_region vp_get_shm_region,.disable_vq_and_reset vp_modern_disable_vq_and_reset,.enable_vq_after_reset vp_modern_enable_vq_after_reset, }; virtio_pci_config_ops结构中的成员函数通常是virtio PCI代理设备的IO操作包括读写virtio PCI代理设备的PIO和MMIO如get_status和set_status成员对应的vp_get_status函数和vp_set_status函数。分别来看 get_status 根据struct virtio_config_ops中的说明 get_status: read the status byte  *    vdev: the virtio_device  *    Returns the status byte get_status的作用是读取状态字节。有一个参数vdev代表了virtio device。返回值为读取到的状态字节。 get_status所指向的vp_get_status函数也在Linux内核源码/drivers/virtio/virtio_pci_modern.c中代码如下 /* config-{get,set}_status() implementations */ static u8 vp_get_status(struct virtio_device *vdev) {struct virtio_pci_device *vp_dev to_vp_device(vdev);return vp_modern_get_status(vp_dev-mdev); } vp_modern_get_status函数在Linux内核源码/drivers/virtio/virtio_pci_modern_dev.c中代码如下 /** vp_modern_get_status - get the device status* mdev: the modern virtio-pci device** Returns the status read from device*/ u8 vp_modern_get_status(struct virtio_pci_modern_device *mdev) {struct virtio_pci_common_cfg __iomem *cfg mdev-common;return vp_ioread8(cfg-device_status); } EXPORT_SYMBOL_GPL(vp_modern_get_status); set_status set_status: write the status byte  *    vdev: the virtio_device  *    status: the new status byte set_status的作用是写入状态字节。有两个参数vdev代表了virtio devicestatus为新的要写入的状态字节。 set_status所指向的vp_set_status函数也在Linux内核源码/drivers/virtio/virtio_pci_modern.c中代码如下 static void vp_set_status(struct virtio_device *vdev, u8 status) {struct virtio_pci_device *vp_dev to_vp_device(vdev);/* We should never be setting status to 0. */BUG_ON(status 0);vp_modern_set_status(vp_dev-mdev, status); } vp_modern_set_status函数在Linux内核源码/drivers/virtio/virtio_pci_modern_dev.c中代码如下 /** vp_modern_set_status - set status to device* mdev: the modern virtio-pci device* status: the status set to device*/ void vp_modern_set_status(struct virtio_pci_modern_device *mdev,u8 status) {struct virtio_pci_common_cfg __iomem *cfg mdev-common;/** Per memory-barriers.txt, wmb() is not needed to guarantee* that the cache coherent memory writes have completed* before writing to the MMIO region.*/vp_iowrite8(status, cfg-device_status); } EXPORT_SYMBOL_GPL(vp_modern_set_status); vp_modern_get_status和vp_modern_set_status函数直接读写vp_dev-mdev-common-device_status。从前文书QEMU源码全解析 —— virtio14的讲解可知vp_dev-common对应的是virtio PCI代理设备第四个BAR表示的地址中的一段空间。 vp_dev-mdev-common的类型为struct virtio_pci_common_cfg该结构的定义在Linux内核源码/include/uapi/linux/virtio_pci.h中代码如下 /* Fields in VIRTIO_PCI_CAP_COMMON_CFG: */ struct virtio_pci_common_cfg {/* About the whole device. */__le32 device_feature_select; /* read-write */__le32 device_feature; /* read-only */__le32 guest_feature_select; /* read-write */__le32 guest_feature; /* read-write */__le16 msix_config; /* read-write */__le16 num_queues; /* read-only */__u8 device_status; /* read-write */__u8 config_generation; /* read-only *//* About a specific virtqueue. */__le16 queue_select; /* read-write */__le16 queue_size; /* read-write, power of 2. */__le16 queue_msix_vector; /* read-write */__le16 queue_enable; /* read-write */__le16 queue_notify_off; /* read-only */__le32 queue_desc_lo; /* read-write */__le32 queue_desc_hi; /* read-write */__le32 queue_avail_lo; /* read-write */__le32 queue_avail_hi; /* read-write */__le32 queue_used_lo; /* read-write */__le32 queue_used_hi; /* read-write */ }; struct virtio_pci_common_cfg的每一个成员都表示一个virtio PCI代理设备modern MMIO地址空间中对应的值读写这写成员都会陷入到QEMU中。比如上面的读取或者设置设备状态的device_status成员其地址从virtio_pci_common_cfg结构开始的偏移20字节处44442220所以读写该地址的时候会陷入到QEMU中并且地址是virtio设备的common MemoryRegion偏移20字节处。该MemoryRegion对应的回调操作结构是common_ops类型为MemoryRegionOps。 common_ops在hw/virtio/virtio-pci.c中初始化代码如下 static void virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy,const char *vdev_name) {static const MemoryRegionOps common_ops {.read virtio_pci_common_read,.write virtio_pci_common_write,.impl {.min_access_size 1,.max_access_size 4,},.endianness DEVICE_LITTLE_ENDIAN,};…… } 回到struct_pci_config_ops。 static const struct virtio_config_ops virtio_pci_config_ops {.get vp_get,.set vp_set,.generation vp_generation,.get_status vp_get_status,.set_status vp_set_status,.reset vp_reset,.find_vqs vp_modern_find_vqs,.del_vqs vp_del_vqs,.synchronize_cbs vp_synchronize_vectors,.get_features vp_get_features,.finalize_features vp_finalize_features,.bus_name vp_bus_name,.set_vq_affinity vp_set_vq_affinity,.get_vq_affinity vp_get_vq_affinity,.get_shm_region vp_get_shm_region,.disable_vq_and_reset vp_modern_disable_vq_and_reset,.enable_vq_after_reset vp_modern_enable_vq_after_reset, }; virtio_pci_config_ops的各个函数封装了这些I/O操作不仅是MMO操作还有PIO操作。virtio设备可以通过此结构中的各个回调函数来驱动设备。 本回就讲到这里。下一回以virtio balloon设备的初始化过程为例分析virtio设备的初始化过程即上一回讲到的virtio驱动初始化设备的过程中的“执行设备相关的初始化操作”一步。 欲知后事如何且看下回分解。
http://www.pierceye.com/news/232177/

相关文章:

  • 网站建设感悟平面设计在哪里接单
  • 网站建设中html网页软件开发定制外包服务商
  • 山东seo网站推广河南定制网站建设企业
  • 网站建设文献文档单产品网站建设
  • 唐山网站建设自主开发宁波北仑做公司网站
  • 廊坊网页模板建站专业网站建设公司排名
  • 广州本地生活appseo百度百科
  • 成都产品网站建设镜像网站是怎么做的
  • 网站建设需求分析范例中国建设信息网站
  • 提供网站建设工具的品牌如何自己开个网站平台
  • 站长工具seo综合查询怎么去掉百家号查询排名数据查询
  • 网站怎么做商家定位注册网站不用手机短信验证的网站
  • 郑州医疗网站建设线下推广团队
  • 合肥网站推广 公司哪家好阿里云注销网站
  • 手机网站调用分享网站用户体验存在问题
  • 淘宝网官方网站路飞和女帝做h的网站
  • app网站设计制作360网站 备案
  • 网站建设多久能学会内丘网站建设案例
  • 网站设计要素 优帮云卖东西专业网站网上
  • 做古风人物小图的网站或软件东莞附近的网络推手公司
  • 东莞专业的单位网站建设江苏网站建设定制
  • 宁夏建设工程造价站网站东营网站seo外包
  • 推销网站建设今天重大新闻文字
  • 网站上线过程网站开发系统需求说明书
  • it外包行业江门seo网络推广
  • 深圳石岩建网站判断网站模板版本
  • 梅州市住房和城乡建设局网站东营网站
  • 免费手机端网站模板下载工具windows怎么做网站
  • 新乡网站自然优化本地电脑如何做网站服务器
  • 网站备案是域名备案还是服务器备案辽宁天一建设有限责任公司网站