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

驱动开发系列54 - Linux Graphics QXL显卡驱动代码分析(一)设备初始化

一:概述

        QXL 是QEMU支持的一种虚拟显卡,用于虚拟化环境中的图形加速,旨在提高虚拟机的图形显示和远程桌面的用户体验;QEMU 也称 Quick Emulator,快速仿真器,是一个开源通用的仿真和虚拟化工具,可以模拟不同架构的计算机以及运行虚拟机。本文介绍下QXL 虚拟显卡驱动,即Linux 内核代码中QXL显卡驱动部分。看看它是如何支持QEMU虚拟显卡的。 QXL代码分析基于v6.15-rc2内核版本。

二:模块初始化

        QXL 虚拟显卡是一个PCI设备,它需要QXL显卡驱动支持显示模式 (modeset) 设置能力,即支持在内核设置输出参数的能力(分辨率,帧率)。比如将显示器设置成1920x1080分辨率。同时QXL显卡驱动在Linux 内核代码中,它是一个独立的内核模块,代码位置是linux/drivers/gpu/drm/qxl。所以QXL内核模块的初始化方式是:

drm_module_pci_driver_if_modeset(qxl_pci_driver, qxl_modeset);

        这行代码的意思是:QXL 模块告诉内核,我是一个 PCI 设备驱动模块(基于 DRM 框架),如果你支持 modeset,那我会自动注册 qxl_pci_driver。

三:PCI设备初始化

        QXL显卡是PCI设备,所以前面模块初始化时注册了qxl_pci_driver,  下面看看 qxl_pci_driver的定义;

static struct pci_driver qxl_pci_driver = {.name = DRIVER_NAME,.id_table = pciidlist,.probe = qxl_pci_probe,.remove = qxl_pci_remove,.shutdown = qxl_pci_shutdown,.driver.pm = &qxl_pm_ops,
};

       这段代码的意思是:我这个 QXL 驱动支持这些 PCI ID,如果你发现这样的设备,就用qxl_pci_probe()  来初始化,拔出时用 qxl_pci_remove() 清理,关机时调用 qxl_pci_shutdown,需要挂起/恢复就用 qxl_pm_ops 处理。 

        下面这个 pciidlist 是 QXL 驱动和 PCI 总线的匹配表:

static const struct pci_device_id pciidlist[] = {{ 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0 },{ 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_OTHER << 8, 0xffff00, 0 },{ 0, 0, 0 },
};

      这里面每个结构是一个 struct pci_device_id,用于匹配设备的 Vendor ID、Device ID、Class 等信息:

{.vendor     = 0x1b36,     // 厂商 ID(Red Hat QEMU 的 PCI 厂商 ID).device     = 0x0100,     // 设备 ID(QXL 虚拟显卡的 ID).subvendor  = PCI_ANY_ID, // 子系统厂商 ID(任意).subdevice  = PCI_ANY_ID, // 子系统设备 ID(任意).class      = PCI_CLASS_DISPLAY_VGA << 8, // 设备类(VGA 显卡类).class_mask = 0xffff00,   // 匹配 class 的掩码.driver_data = 0          // 可用于传递自定义参数,这里设为 0
}

        当内核检测到有匹配的PCI设备插入时,即检测到QXL显卡设备时,就调用设备初始化函数qxl_pci_probe,下面我们看看它做了什么工作:


static int
qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{struct qxl_device *qdev;int ret;if (pdev->revision < 4) {DRM_ERROR("qxl too old, doesn't support client_monitors_config,"" use xf86-video-qxl in user mode");return -EINVAL; /* TODO: ENODEV ? */}qdev = devm_drm_dev_alloc(&pdev->dev, &qxl_driver,struct qxl_device, ddev);if (IS_ERR(qdev)) {pr_err("Unable to init drm dev");return -ENOMEM;}ret = pci_enable_device(pdev);if (ret)return ret;ret = aperture_remove_conflicting_pci_devices(pdev, qxl_driver.name);if (ret)goto disable_pci;if (pci_is_vga(pdev) && pdev->revision < 5) {ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO);if (ret) {DRM_ERROR("can't get legacy vga ioports\n");goto disable_pci;}}ret = qxl_device_init(qdev, pdev);if (ret)goto put_vga;ret = qxl_modeset_init(qdev);if (ret)goto unload;drm_kms_helper_poll_init(&qdev->ddev);/* Complete initialization. */ret = drm_dev_register(&qdev->ddev, ent->driver_data);if (ret)goto modeset_cleanup;drm_client_setup(&qdev->ddev, NULL);return 0;modeset_cleanup:qxl_modeset_fini(qdev);
unload:qxl_device_fini(qdev);
put_vga:if (pci_is_vga(pdev) && pdev->revision < 5)vga_put(pdev, VGA_RSRC_LEGACY_IO);
disable_pci:pci_disable_device(pdev);return ret;
}

        这个代码做的第一件事就是分配一个qxl_device设备;并注册了一个 qxl_driver 驱动,与qxl_device建立绑定关系;关于qxl_device, qxl_driver 后面再说;这里可以理解为他们是QXL设备,和对应的QXL设备驱动。  

        这个代码做的第二件事就是打开PCI BAR和使能PCI中断访问。也就是说PCI BAR 是PCI设备暴露的“资源入口”,通过它内核可以访问显卡的内存,I/O端口和使能中断,实现真正驱动硬件的能力;PCI设备可以产生中断,比如GPU渲染完成时通知CPU。

        这个代码做的第三件事就是初始化QXL设备的显存,寄存器等,这个后面再详细展开说。

        这个代码做的第四件事就是配置QXL设备的显示输出(KMS),比如CRTC,Encoder,Connector,这个后面再详细展开说。

        这个代码做的第五件事就是向内核注册QXL设备,这样用户空间才能通过 /dev/dri/cardX 访问到该设备。 

四:QXL设备初始化

        前面在 qxl_pci_probe 分配和初始化了 qxl_device,并将其和qxl_drvier建立了绑定关系。下面看看qxl_driver 和 qxl_device 的定义。

static struct drm_driver qxl_driver = {.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_CURSOR_HOTSPOT,.dumb_create = qxl_mode_dumb_create,.dumb_map_offset = drm_gem_ttm_dumb_map_offset,
#if defined(CONFIG_DEBUG_FS).debugfs_init = qxl_debugfs_init,
#endif.gem_prime_import_sg_table = qxl_gem_prime_import_sg_table,DRM_FBDEV_TTM_DRIVER_OPS,.fops = &qxl_fops,.ioctls = qxl_ioctls,.num_ioctls = ARRAY_SIZE(qxl_ioctls),.name = DRIVER_NAME,.desc = DRIVER_DESC,.major = 0,.minor = 1,.patchlevel = 0,.release = qxl_drm_release,
};

        这个代码定义了一个 drm_driver 结构体,从这里也可以看出,QXL驱动确实是基于DRM框架的(DRM介绍详见本专栏的相关文章)。 drm_device 是QXL显卡在Linux DRM 框架中的核心驱动结构,这个结构注册后会与DRM核心框架配合,为显卡提供设备初始化,缓冲区管理,图形输出等功能。 


struct qxl_device {struct drm_device ddev;resource_size_t vram_base, vram_size;resource_size_t surfaceram_base, surfaceram_size;resource_size_t rom_base, rom_size;struct qxl_rom *rom;struct qxl_mode *modes;struct qxl_bo *monitors_config_bo;struct qxl_monitors_config *monitors_config;/* last received client_monitors_config */struct qxl_monitors_config *client_monitors_config;int io_base;void *ram;struct qxl_mman		mman;struct qxl_gem		gem;void *ram_physical;struct qxl_ring *release_ring;struct qxl_ring *command_ring;struct qxl_ring *cursor_ring;struct qxl_ram_header *ram_header;struct qxl_bo *primary_bo;struct qxl_bo *dumb_shadow_bo;struct qxl_head *dumb_heads;struct qxl_memslot main_slot;struct qxl_memslot surfaces_slot;spinlock_t	release_lock;struct idr	release_idr;uint32_t	release_seqno;atomic_t	release_count;wait_queue_head_t release_event;spinlock_t release_idr_lock;struct mutex	async_io_mutex;unsigned int last_sent_io_cmd;/* interrupt handling */atomic_t irq_received;atomic_t irq_received_display;atomic_t irq_received_cursor;atomic_t irq_received_io_cmd;unsigned int irq_received_error;wait_queue_head_t display_event;wait_queue_head_t cursor_event;wait_queue_head_t io_cmd_event;struct work_struct client_monitors_config_work;/* debugfs */struct qxl_debugfs	debugfs[QXL_DEBUGFS_MAX_COMPONENTS];unsigned int debugfs_count;struct mutex		update_area_mutex;struct idr	surf_id_idr;spinlock_t surf_id_idr_lock;int last_alloced_surf_id;struct mutex surf_evict_mutex;struct io_mapping *vram_mapping;struct io_mapping *surface_mapping;/* */struct mutex release_mutex;struct qxl_bo *current_release_bo[3];int current_release_bo_offset[3];struct work_struct gc_work;struct drm_property *hotplug_mode_update_property;int monitors_config_width;int monitors_config_height;
};

        qxl_device 是QXL DRM驱动中定义的“设备结构体”,代表一个QXL显卡实例,在驱动运行时用于管理显卡的状态、资源、内存和与内核/用户空间交互。它是QXL驱动的核心数据结构,每个被探测到的QXL设备(比如前面说的通过PCI探测)都会分配这样一个结构并初始化,贯穿设备的整个生命周期。 

        下面看看QXL设备驱动是如何操作QXL设备的。正戏开始。。。

相关文章:

驱动开发系列54 - Linux Graphics QXL显卡驱动代码分析(一)设备初始化

一&#xff1a;概述 QXL 是QEMU支持的一种虚拟显卡&#xff0c;用于虚拟化环境中的图形加速&#xff0c;旨在提高虚拟机的图形显示和远程桌面的用户体验&#xff1b;QEMU 也称 Quick Emulator&#xff0c;快速仿真器&#xff0c;是一个开源通用的仿真和虚拟化工具&#xff0c;可…...

通过IP计算分析归属地

在产品中可能存在不同客户端&#xff0c;请求同一个服务端接口的场景。 例如小程序和App或者浏览器中&#xff0c;如果需要对请求的归属地进行分析&#xff0c;前提是需要先获取请求所在的国家或城市&#xff0c;这种定位通常需要主动授权&#xff0c;而用户一般是不愿意提供的…...

【网络原理】从零开始深入理解HTTP的报文格式(二)

本篇博客给大家带来的是网络HTTP协议的知识点, 续上篇文章,接着介绍HTTP的报文格式. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅…...

【前缀和】二维前缀和(模板题)

DP35 【模板】二维前缀和 DP35 【模板】二维前缀和 ​ 给你一个 n 行 m 列的矩阵 A ,下标从 1 开始,接下来有 q 次查询,每次查询输入 4 个参数 x1 , y1 , x2 , y2。 ​ 请输出以 (x1, y1) 为左上角,(x2,y2) 为右下角的子矩阵的和。 输入描述: ​ 第一行包含三个整数 …...

【开源工具】Python打造智能IP监控系统:邮件告警+可视化界面+配置持久化

&#x1f310;【开源工具】Python打造智能IP监控系统&#xff1a;邮件告警可视化界面配置持久化 &#x1f308; 个人主页&#xff1a;创客白泽 - CSDN博客 &#x1f525; 系列专栏&#xff1a;&#x1f40d;《Python开源项目实战》 &#x1f4a1; 热爱不止于代码&#xff0c;热…...

kotlin 过滤 filter 函数的作用和使用场景

1. filter 函数的作用 filter 是 Kotlin 集合操作中的一个高阶函数&#xff0c;用于根据指定条件从集合中筛选出符合条件的元素。 作用&#xff1a;遍历集合中的每个元素&#xff0c;并通过给定的 lambda 表达式判断是否保留该元素。返回值&#xff1a;一个新的集合&#xff…...

Java泛型(补档)

核心概念 Java 泛型是 Java SE 1.5 引入的一项重要特性&#xff0c;它的核心思想是 参数化类型&#xff08;Parameterized Types&#xff09;&#xff0c;即通过将数据类型作为参数传递给类、接口或方法&#xff0c;使代码能够灵活地处理多种类型&#xff0c;同时保证类型安全性…...

C语言发展史:从Unix起源到现代标准演进

C语言发展史&#xff1a;从Unix起源到现代标准演进 C语言的诞生与早期发展 C语言的起源可以追溯到上世纪70年代初期&#xff0c;但其真正的萌芽始于1969年的夏天。在计算机发展史上&#xff0c;这是一个具有划时代意义的时刻。 当时&#xff0c;Ken Thompson和Dennis Ritchi…...

nginx 代理时怎么更改 Remote Address 请求头

今天工作中遇到用 localhost 访问网站能访问后台 api&#xff0c;但是用本机IP地址后就拒绝访问&#xff0c;我怀疑是后台获取 Remote Address 然后设置白名单了只能 localhost 访问。 想用 nginx 更改 Remote Address server {listen 8058;server_name localhost;loca…...

解决STM32待机模式无法下载程序问题的深度探讨

在现代嵌入式系统开发中&#xff0c;STM32系列微控制器因其高性能、低功耗和丰富的外设资源而广受欢迎。然而&#xff0c;开发者在使用STM32时可能会遇到一个问题&#xff1a;当微控制器进入待机模式后&#xff0c;无法通过调试接口&#xff08;如SWD或JTAG&#xff09;下载程序…...

进程、线程、进程间通信Unix Domain Sockets (UDS)

进程、线程、UDS 进程和线程进程间通信Unix Domain Sockets (UDS)UDS的核心适用场景和用途配置UDS的几种主要方式socketpair() 基本配置流程socketpair() 进阶——传递文件描述符 补充socketpair() 函数struct msghdr 结构体struct iovecstruct cmsghdrstruct iovec 、struct m…...

大数据平台与数据仓库的核心差异是什么?

随着数据量呈指数级增长&#xff0c;企业面临着如何有效管理、存储和分析这些数据的挑战。 大数据平台和 数据仓库作为两种主流的数据管理工具&#xff0c;常常让企业在选型时感到困惑&#xff0c;它们之间的界限似乎越来越模糊&#xff0c;功能也有所重叠。本文旨在厘清这两种…...

Hadoop虚拟机中配置hosts

&#xff08; 一&#xff09;修改虚拟机的主机名 默认情况下&#xff0c;本机的名称叫&#xff1a;localhost。 我们进入linux系统之后&#xff0c;显示出来的就是[rootlocalhost ~]# 。为了方便后面我们更加便捷地访问这台主机&#xff0c;而不是通过ip地址&#xff0c;我们要…...

a-upload组件实现文件的上传——.pdf,.ppt,.pptx,.doc,.docx,.xls,.xlsx,.txt

实现下面的上传/下载/删除功能&#xff1a;要求支持&#xff1a;【.pdf,.ppt,.pptx,.doc,.docx,.xls,.xlsx,.txt】 分析上面的效果图&#xff0c;分为【上传】按钮和【文件列表】功能&#xff1a; 解决步骤1&#xff1a;上传按钮 直接上代码&#xff1a; <a-uploadmultip…...

QCefView应用和网页的交互

一、demo的主要项目文件 结合QCefView自带的demo代码 main.cpp #include #include <QCefContext.h> #include “MainWindow.h” int main(int argc, char* argv[]) { QApplication a(argc, argv); // build QCefConfig QCefConfig config; config.setUserAgent(“QCef…...

C++,设计模式,【建造者模式】

文章目录 通俗易懂的建造者模式&#xff1a;手把手教你造电脑一、现实中的建造者困境二、建造者模式核心思想三、代码实战&#xff1a;组装电脑1. 产品类 - 电脑2. 抽象建造者 - 装机师傅3. 具体建造者 - 电竞主机版4. 具体建造者 - 办公主机版5. 指挥官 - 装机总控6. 客户端使…...

Axure疑难杂症:中继器制作下拉菜单(多级中继器高级交互)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 本文视频课程记录于上述地址第五章中继器专题第11节 课程主题:中继器制作下拉菜单 主要内容:创建条件选区、多级中继器…...

科研 | 光子技术为人工智能注入新动力

译《Nature》25.4.9 发表文章《A photonic processing boost for AI》 ▶ 基于人工智能&#xff08;artificial intelligence, AI&#xff09;的系统正被越来越广泛地应用于从基因数据解码到自动驾驶的各类任务。但随着AI模型的规模和应用的扩大&#xff0c;性能天花板与能耗壁…...

SQL语句练习 自学SQL网 多表查询

目录 Day 6 用JOINs进行多表联合查询 Day 7 外连接 OUTER JOINs Day 8 外连接 特殊关键字 NULLs Day 6 用JOINs进行多表联合查询 SELECT * FROM Boxoffice INNER JOIN movies ON movies.idboxoffice.Movie_id;SELECT * FROM Boxoffice INNER JOIN moviesON movies.idboxoffi…...

北京亦庄机器人马拉松:人机共跑背后的技术突破与产业启示

2025年4月19日&#xff0c;北京亦庄举办了一场具有里程碑意义的科技赛事——全球首个人形机器人半程马拉松。这场人类与20支机器人战队共同参与的21.0975公里竞速&#xff0c;不仅创造了人形机器人连续运动的最长纪录&#xff0c;更成为中国智能制造领域的综合性技术验证平台。…...

大连理工大学选修课——机器学习笔记(6):决策树

决策树 决策树概述 决策树——非参数机器学习方法 参数方法&#xff1a; 参数估计是定义在整个空间的模型 所有训练数据参与估算 所有的检验输入都用相同的模型和参数 非参数方法&#xff1a; 非参数估计采用局部模型 输入空间被分裂为一系列可以用距离度量的局部空间…...

现代前端工具链深度解析:从包管理到构建工具的完整指南

前言 在当今快速发展的前端生态中&#xff0c;高效的工具链已经成为开发者的必备利器。一个优秀的前端工具链可以显著提升开发效率、优化项目性能并改善团队协作体验。本文将深入探讨现代前端开发中最核心的两大工具类别&#xff1a;包管理工具(npm/yarn)和构建工具(Webpack/V…...

[C语言]猜数字游戏

文章目录 一、游戏思路揭秘二、随机数生成大法1、初探随机数&#xff1a;rand函数的魔力2、随机数种子&#xff1a;时间的魔法3、抓住时间的精髓&#xff1a;time函数 三、完善程序四、游戏成果1、游戏效果2、源代码 一、游戏思路揭秘 猜数字游戏&#xff0c;这个听起来就让人…...

【Linux】g++安装教程

Linux上安装g教程 实现c语言在Linux上编译运行 1. 更新软件包列表 打开终端&#xff0c;先更新软件包列表以确保获取最新版本信息&#xff1a; sudo apt update2. 安装 build-essential 工具包 build-essential 包含 g、gcc、make 和其他编译所需的工具&#xff1a; sudo…...

MQTT - Android MQTT 编码实战(MQTT 客户端创建、MQTT 客户端事件、MQTT 客户端连接配置、MQTT 客户端主题)

Android MQTT 编码实战 1、Settting 在项目级 build.gradle 目录下导入 MQTT 客户端依赖 implementation org.eclipse.paho:org.eclipse.paho.mqttv5.client:1.2.5 implementation org.eclipse.paho:org.eclipse.paho.android.service:1.1.1AndroidManifest.xml&#xff0c;…...

Redis分布式锁使用以及对接支付宝,paypal,strip跨境支付

本章重点在于如何使用redis的分布式锁来锁定库存。减少超卖&#xff0c;同时也对接了支付宝&#xff0c;paypal&#xff0c;strip跨境支付 第一步先建立一个商品表 CREATE TABLE sys_product (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键,code varchar(60) DEFAUL…...

沙箱逃逸(Python沙盒逃逸深度解析)

沙箱逃逸&#xff08;Python沙盒逃逸深度解析&#xff09; 一、沙盒逃逸的核心目标 执行系统命令 通过调用os.system、subprocess.Popen等函数执行Shell命令&#xff0c;例如读取文件或反弹Shell。 文件操作 读取敏感文件&#xff08;如/etc/passwd&#xff09;、写入后门文件…...

k8s-Pod生命周期

初始化容器 初始化容器是在pod的主容器启动之前要运行的容器&#xff0c;主要是做一些主容器的前置工作&#xff0c;它具有两大特征&#xff1a; 1. 初始化容器必须运行完成直至结束&#xff0c;若某初始化容器运行失败&#xff0c;那么kubernetes需要重启它直到成功完成 2. 初…...

基于Springboot + vue实现的中医院问诊系统

项目描述 本系统包含管理员、医生、用户三个角色。 管理员角色&#xff1a; 用户管理&#xff1a;管理系统中所有用户的信息&#xff0c;包括添加、删除和修改用户。 配置管理&#xff1a;管理系统配置参数&#xff0c;如上传图片的路径等。 权限管理&#xff1a;分配和管理…...

computed计算值为什么还可以依赖另外一个computed计算值?

在 Vue&#xff08;或类似的响应式框架&#xff09;中&#xff0c;computed 计算属性之所以可以依赖另一个 computed 属性&#xff0c;是因为&#xff1a; ✅ 本质上 computed 是响应式依赖的“派生值” 每个 computed 本质上就是一个 基于其他响应式数据计算出来的值。 当你在…...

近期实践总结

一、计算机二级考试到底教会了我们什么&#xff1f; 1、概况 根据本人复习、考试的经验&#xff0c;不难发现里面的试题或多或少有些死板&#xff08;甚至可以说落后于时代&#xff09;&#xff0c;当今时代已经不是二十年前什么都需要手搓的时代了&#xff0c;引擎、集成类软…...

Arduion 第一天,变量的详细解析

Arduino变量详解与嵌入式开发扩展 一、变量基础篇 1.1 变量声明与初始化 <ARDUINO>int ledPin 13; // 声明并初始化float sensorValue; // 先声明后赋值unsigned long startTime; // 无符号长整型void setup() {sensorValue analogRead(A0) *…...

【每日八股】复习 MySQL Day3:锁

文章目录 昨日内容复习MySQL 使用 B 树作为索引的优势是什么&#xff1f;索引有哪几种&#xff1f;什么是最左匹配原则&#xff1f;索引区分度&#xff1f;联合索引如何排序&#xff1f;使用索引有哪些缺陷&#xff1f;什么时候需要建立索引&#xff0c;什么时候不需要&#xf…...

2025年KBS新算法 SCI1区TOP:长颖燕麦优化算法AOO,深度解析+性能实测

目录 1.摘要2.算法原理3.结果展示4.参考文献5.文章&代码获取 1.摘要 本文提出了一种新颖的元启发式算法——长颖燕麦优化算法&#xff08;AOO&#xff09;&#xff0c;该算法灵感来自动画燕麦在环境中的自然行为。AOO模拟了长颖燕麦的三种独特行为&#xff1a;(i) 通过自然…...

1.4 点云数据获取方式——结构光相机

图1-4-1结构光相机 结构光相机作为获取三维点云数据的关键设备,其工作原理基于主动式测量技术。通过投射已知图案,如条纹、点阵、格雷码等,至物体表面,这些图案会因物体表面的高度变化而发生变形。与此同时,利用相机从特定...

2025.4.29总结

工作&#xff1a;最近手头活变得多起来了&#xff0c;毕竟要测两个版本&#xff0c;有时候觉得很奇怪&#xff0c;活少的时候&#xff0c;又想让别人多分点活&#xff0c;活多的时候&#xff0c;又会有些许不自然。这种反差往往伴随着项目的节奏&#xff0c;伴随着两个极端。所…...

初探RAG

源码 核心工作流程 读取文件的内容将内容保存在向量数据库检索向量数据库用户的问题用户问题 上下文【向量数据】 > LLM 读取文件内容【pdf为例】 from pdfminer.high_level import extract_pages from pdfminer.layout import LTTextContainerclass PDFFileLoader():d…...

AIGC(生成式AI)技术全景图:从文本到图像的革命

AIGC&#xff08;生成式AI&#xff09;技术全景图&#xff1a;从文本到图像的革命 前言 生成式人工智能&#xff08;AIGC&#xff09;正以惊人的速度重塑数字内容的生产方式。从GPT系列模型的文本生成&#xff0c;到Stable Diffusion的图像创作&#xff0c;再到Sora的视频合成…...

通信协议:数字世界的隐形语言——从基础认知到工程实践-优雅草卓伊凡

通信协议&#xff1a;数字世界的隐形语言——从基础认知到工程实践-优雅草卓伊凡 一、理解通信协议&#xff1a;数字世界的”隐形语法” 1.1 通信协议的不可见性与现实存在 通信协议如同空气中的无线电波&#xff0c;虽然看不见摸不着&#xff0c;却实实在在支撑着现代数字世…...

RPC复习

RPC复习 RPC (远程过程调用) 全面解析一、RPC 定义与核心作用1. 什么是RPC&#xff1f;2. 核心作用 二、主流RPC框架对比三、RPC适用场景四、RPC的缺陷五、RPC vs REST vs GraphQL六、Java实现案例&#xff1a;使用Dubbo框架案例描述1. 环境准备2. 定义服务接口3. 服务提供方实…...

Express 文件上传不迷路:req.files 一次性讲明白

前言 在开发后台接口的江湖中,文件上传堪称“隐藏副本”,难度不大但坑点极多。本来只想优雅接收一张图片,结果 undefined、报错、路径错乱轮番登场,逼得人想重拾卖烤红薯的梦想。别慌,本文将用轻松幽默的方式,深入拆解 req.files.file 的每个属性,从前端表单到后台处理…...

Leetcode 3530. Maximum Profit from Valid Topological Order in DAG

Leetcode 3530. Maximum Profit from Valid Topological Order in DAG 1. 解题思路2. 代码实现 题目链接&#xff1a;3530. Maximum Profit from Valid Topological Order in DAG 1. 解题思路 这一题的整体思路就是一个动态规划的思路&#xff0c;我们只需要在当前可以访问的…...

Mysql中索引的知识

Mysql中的索引的定义和种类 核心概念&#xff1a;索引是什么&#xff1f; 想象一下你有一本很厚的书&#xff0c;你想找到其中关于某个特定主题的内容。你有两种方法&#xff1a; 从头到尾翻阅整本书&#xff1a;这就像数据库中的全表扫描 (Full Table Scan)。如果书很长&…...

VSCode Verilog编辑仿真环境搭建

VSCode Verilog环境搭建 下载Iverilog安装Iverilog验证安装VS Code安装插件 下载Iverilog 官网下载Iverilog 安装Iverilog 一定要勾选这两项 建议勾选这两项 验证安装 运行Windows PowerShell输入命令&#xff1a;iverilog输入命令&#xff1a;Get-Command gtkwave …...

linux修改环境变量

添加环境变量注意事项。 vim ~/.bashrc 添加环境变量时&#xff0c;需要source ~/.bashrc后才能有效。同时只对当前shell窗口有效&#xff0c;当打开另外的shell窗口时&#xff0c;需要重新source才能起效。 1.修改bashrc文件后 2.source后打开另一个shell窗口则无效&#xff…...

为什么要学习《金刚经》

《金刚经》作为佛教般若经典的核心&#xff0c;以"缘起性空"为思想根基&#xff0c;通过佛陀与须菩提的对话&#xff0c;揭示了破除执著、见真实相的智慧。 以下从核心要义、精髓段落和现实应用三个维度进行解读&#xff1a; 一、核心思想精髓 1. "凡所有相&am…...

【阿里云大模型高级工程师ACP习题集】2.7 通过微调增强模型能力 (上篇)(⭐️⭐️⭐️ 重点章节!!!)

习题集: 【单选题】在大模型微调中,与提示工程和RAG相比,微调的独特优势在于( ) A. 无需外部工具即可提升模型表现 B. 能让模型学习特定领域知识,提升底层能力 C. 可以更高效地检索知识 D. 能直接提升模型的知识边界,无需训练 【多选题】以下关于机器学习和传统编程的说…...

Docker 容器双网卡访问物理雷达网络教程

作者&#xff1a; 陈梓洋 环境&#xff1a; ubuntu 22.04lts 时间&#xff1a; 2025年4月29日 Docker 容器双网卡访问物理雷达网络教程 这个教程适用于这样的场景&#xff1a;容器保留原有 ROS 通信网络&#xff08;如 bridge 网络&#xff09;&#xff0c;同时需要访问一个物…...

C++:Lambda表达式

C&#xff1a;Lambda表达式 C中lambda的基本语法1. 捕获列表&#xff08;Capture List&#xff09;2. 示例代码示例 1&#xff1a;简单的lambda示例 2&#xff1a;捕获变量示例 3&#xff1a;按引用捕获示例 4&#xff1a;捕获所有变量示例 5&#xff1a;作为函数参数 3. lambd…...

Vim 中替换字符或文本

在 Vim 中替换字符或文本可以使用 替换命令&#xff08;substitute&#xff09;&#xff0c;其基本语法为&#xff1a; :[range]s/old/new/[flags]1. 基本替换 命令说明:s/foo/bar/替换当前行的第一个 foo 为 bar:s/foo/bar/g替换当前行的 所有 foo 为 bar:%s/foo/bar/g替换 …...