Nouveau源码分析(三):NVIDIA设备初始化之nouveau_drm_probe

本文深入解析Nouveau驱动中的nouveau_drm_probe函数,详述NVIDIA设备初始化过程。从PCI模块扫描、设备匹配到nouveau_drm_probe的调用,探讨NV设备结构体创建、engine和object结构的初始化,以及Bus-Mastering的启用和DRM设备注册等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Nouveau源码分析(三)

向DRM注册了Nouveau驱动之后,内核中的PCI模块就会扫描所有没有对应驱动的设备,然后和nouveau_drm_pci_table对照.

对于匹配的设备,PCI模块就调用对应的probe函数,也就是nouveau_drm_probe.

// /drivers/gpu/drm/nouveau/nouveau_drm.c
281 static int nouveau_drm_probe(struct pci_dev *pdev,
282                              const struct pci_device_id *pent)
283 {
284         struct nouveau_device *device;
285         struct apertures_struct *aper;
286         bool boot = false;
287         int ret;
288 
289         /* remove conflicting drivers (vesafb, efifb etc) */
290         aper = alloc_apertures(3);
291         if (!aper)
292                 return -ENOMEM;
293 
294         aper->ranges[0].base = pci_resource_start(pdev, 1);
295         aper->ranges[0].size = pci_resource_len(pdev, 1);
296         aper->count = 1;
297 
298         if (pci_resource_len(pdev, 2)) {
299                 aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
300                 aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
301                 aper->count++;
302         }
303 
304         if (pci_resource_len(pdev, 3)) {
305                 aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
306                 aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
307                 aper->count++;
308         }
309 
310 #ifdef CONFIG_X86
311         boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
312 #endif
313         if (nouveau_modeset != 2)
314                 remove_conflicting_framebuffers(aper, "nouveaufb", boot);
315         kfree(aper);
316 
317         ret = nouveau_device_create(pdev, NOUVEAU_BUS_PCI,
318                                     nouveau_pci_name(pdev), pci_name(pdev),
319                                     nouveau_config, nouveau_debug, &device);
320         if (ret)
321                 return ret;
322 
323         pci_set_master(pdev);
324 
325         ret = drm_get_pci_dev(pdev, pent, &driver);
326         if (ret) {
327                 nouveau_object_ref(NULL, (struct nouveau_object **)&device);
328                 return ret;
329         }
330 
331         return 0;
332 }

第290~315行,分配了一个aper,把资源位置写进去,调用了remove_conflicting_framebuffer,接着释放这个aper.

一行注释和函数名已经说的很明白,就是移除冲突的framebuffer.


第317行,创建一个NV设备的结构体,这个函数我们要仔细看

// /drivers/gpu/drm/nouveau/core/include/engine/device.h
 13 #define nouveau_device_create(p,t,n,s,c,d,u)                                   \
 14         nouveau_device_create_((void *)(p), (t), (n), (s), (c), (d),           \
 15                                sizeof(**u), (void **)u)
 16 
 17 int  nouveau_device_create_(void *, enum nv_bus_type type, u64 name,
 18                             const char *sname, const char *cfg, const char *dbg,
 19                             int, void **);
想起了什么? 对,就是上一节讲的内容,我们还是先来看结构体.

// /drivers/gpu/drm/nouveau/core/include/core/device.h
 65 struct nouveau_device {
 66         struct nouveau_engine base;
 67         struct list_head head;
 68 
 69         struct pci_dev *pdev;
 70         struct platform_device *platformdev;
 71         u64 handle;
 72 
 73         struct nvkm_event event;
 74 
 75         const char *cfgopt;
 76         const char *dbgopt;
 77         const char *name;
 78         const char *cname;
 79         u64 disable_mask;
 80 
 81         enum {
 82                 NV_04    = 0x04,
 83                 NV_10    = 0x10,
 84                 NV_11    = 0x11,
### Nouveau DRM Driver Issue on GPU 0000:01:00.0 Solution For addressing the Nouveau DRM driver issue specifically with the GPU identified as `0000:01:00.0`, several strategies can be employed based on previous experiences and solutions found within similar contexts. #### Disabling Kernel Mode Setting Temporarily During Boot To temporarily disable kernel mode setting (KMS), which is often responsible for display issues related to the Nouveau driver, one should add a boot parameter when starting up the system. This involves accessing the GRUB menu by pressing Shift during startup or using Ctrl+Alt+F1-F6 keys depending upon the setup[^2]. Once at the GRUB screen: - Navigate to the line that begins with 'linux' or 'linux16'. - Add `nomodeset` after any existing parameters like `quiet splash`. - Press F10 or Ctrl+X to continue booting into the operating system with these temporary changes applied. This method allows bypassing potential graphical glitches caused by KMS until more permanent fixes are implemented. #### Permanently Adjusting Grub Configuration File Permanently altering how the system handles graphics drivers requires editing `/etc/default/grub`. By modifying this configuration file, it's possible to ensure that every time the machine boots, certain settings take effect automatically without manual intervention each reboot. ```bash sudo nano /etc/default/grub ``` Within this text editor session, locate the line containing `GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"` and append `nomodeset` so it reads something akin to `"quiet splash nomodeset"`. After saving modifications (`Ctrl+O`) and exiting (`Ctrl+X`): ```bash sudo update-grub ``` Executing this command updates all necessary files ensuring new configurations will apply from next boot onwards[^4]. #### Preventing Nouveau Module Loading via Blacklisting Another approach entails preventing Linux from loading the problematic Nouveau module altogether through blacklisting techniques. Editing another critical configuration file achieves this goal effectively while allowing alternative proprietary NVIDIA drivers installation later if desired. ```bash echo "blacklist nouveau" | sudo tee -a /etc/modprobe.d/blacklist.conf echo "options nouveau modeset=0" | sudo tee -a /etc/modprobe.d/nouveau-kms-off.conf ``` After applying such commands, regenerate initramfs images to incorporate recent alterations before restarting your computer normally. ```bash sudo update-initramfs -u ``` These actions collectively contribute towards mitigating common challenges associated with incompatible open-source graphic card drivers under various distributions of GNU/Linux systems including Debian-based ones where Nouveau conflicts arise frequently due to hardware incompatibilities[^3]. --related questions-- 1. What other methods exist besides disabling KMS for troubleshooting display problems? 2. How does adding `nomodeset` impact overall performance compared to default behavior? 3. Can installing proprietary NVIDIA drivers resolve ongoing issues better than tweaking Nouveau options? 4. Is there an optimal way to switch between different video drivers seamlessly post-installation?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值