win10无线网卡bios设置方法
(bios中无线网卡设置)
为什么要在自制操作系统上写网卡驱动?请看这里:
如何在自制操作系统中编写网卡驱动程序(1)
所以今天,让我们开始第一步:看看其他操作系统上的网卡驱动程序是如何写的?
先看下linux如何在操作系统中与网卡通信?
硬件加电初始化时,BIOS统一检查一切PCI通过设备,为每个设备分配一个物理地址BIOS在设备的配置空间配置空间,驱动程序可以将网卡的普通控制寄存器映射到内存空间,CPU通过访问映射后的虚拟地址来控制网卡的寄存器。
当操作系统初始化时,它是每个PCI一个设备分配pci_dev结构,写下前面分配的物理地址pci_dev的resource字段中。
在网卡驱动程序中序中读取pci_dev中的resource通过函数获取网卡的寄存器配置空间地址pci_resource_start()和pci_resource_end()通过获得空间的起始位置ioremap()将该段位置映射到主存中,以便CPU访问控制网卡I/O和内存空间。
调用pci_resource_start
ioremap( pci_resource_start(pdev, BAR_1), pci_resource_len(pdev, BAR_1) );
pci_resource_start只是宏定义:
/* * These helpers provide future and backwards compatibility * for accessing popular PCI BAR info */// 开始地址#define pci_resource_start(dev, bar)((dev)->resource[(bar)].start)// 结束地址#define pci_resource_end(dev, bar)((dev)->resource[(bar)].end)// 设置标志#define pci_resource_flags(dev, bar)((dev)->resource[(bar)].flags)// 获取长度:(start==0 && start==end)?0:end-start 1;// 这句话是简写,展开后:/// if(start==0 && start==end){ return 0;}else{ return end-start 1;}#define pci_resource_len(dev,bar) \\((pci_resource_start((dev), (bar)) == 0 &&\\ pci_resource_end((dev), (bar)) ==\\ pci_resource_start((dev), (bar))) ? 0 :\\\\ (pci_resource_end((dev), (bar)) -\\ pci_resource_start((dev), (bar)) 1))
它定义了对resouce在结构体列表中resource的start,end字段赋值动作
struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions expansion ROMs */
/* * Resources are tree-like, allowing * nesting etc.. */struct resource{resource_size_t start;resource_size_t end;const char *name;unsigned long flags;unsigned long desc;struct resource *parent, *sibling, *child;};
在linux使用e初始化函数为1000网卡e1000_probe.
该函数执行后,配置网卡和相关协议的结构,绑定中断函数。操作系统可以收到网卡的中断信息,因此可以参考此函数中的代码。
/** * e1000_probe - Device Initialization Routine * @pdev: PCI device information struct * @ent: entry in e1000_pci_tbl * * Returns 0 on success, negative on failure * * e1000_probe initializes an adapter identified by a pci_dev structure. * The OS initialization, configuring of the adapter private structure, * and a hardware reset occur. **/static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent){struct net_device *netdev;struct e1000_adapter *adapter = NULL;struct e1000_hw *hw;static int cards_found;static int global_quad_port_a; /* global ksp3 port a indication */int i, err, pci_using_dac;u16 eeprom_data = 0;u16 tmp = 0;u16 eeprom_apme_mask = E1000_EEPROM_APME;int bars, need_ioport;bool disable_dev = false;/* do not allocate ioport bars when not needed */need_ioport = e1000_is_need_ioport(pdev);if (need_ioport){bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);err = pci_enable_device(pdev);}else{bars = pci_select_bars(pdev, IORESOURCE_MEM);err = pci_enable_device_mem(pdev);}if (err)return err;err = pci_request_selected_regions(pdev, bars, e1000_driver_name);if (err)goto err_pci_reg;pci_set_master(pdev);err = pci_save_state(pdev);if (err)goto err_alloc_etherdev;err = -ENOMEM;netdev = alloc_etherdev(sizeof(struct e1000_adapter));if (!netdev)goto err_alloc_etherdev;SET_NETDEV_DEV(netdev, &pdev->dev);pci_set_drvdata(pdev, netdev);adapter = netdev_priv(netdev);adapter->netdev = netdev;adapter->pdev = pdev;adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);adapter->bars = bars;adapter->need_ioport = need_ioport;hw = &adapter->hw;hw->back = adapter;err = -EIO;hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);if (!hw->hw_addr)goto err_ioremap;if (adapter->need_ioport){for (i = BAR_1; i < PCI_STD_NUM_BARS; i ){if (pci_resource_len(pdev, i) == 0)continue;if (pci_resource_flags(pdev, i) & IORESOURCE_IO){hw->io_base = pci_resource_start(pdev, i);break;}}}/* make ready for any if (hw->...) below */err = e1000_init_hw_struct(adapter, hw);if (err)goto err_sw_init;/* there is a workaround being applied below that limits * 64-bit DMA addresses to 64-bit hardware. There are some * 32-bit adapters that Tx hang when given 64-bit DMA addresses */pci_using_dac = 0;if ((hw->bus_type == e1000_bus_type_pcix) && !dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))ci_using_dac = 1;}else{err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));if (err)r_err("No usable DMA config, aborting\");goto err_dma;}}netdev->netdev_ops = &e1000_netdev_ops;e1000_set_ethtool_ops(netdev);netdev->watchdog_timeo = 5 * HZ;netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);adapter->bd_number = cards_found;/* setup the private structure */err = e1000_sw_init(adapter);if (err)goto err_sw_init;err = -EIO;if (hw->mac_type == e1000_ce4100){hw->ce4100_gbe_mdio_base_virt =ioremap(pci_resource_start(pdev, BAR_1),pci_resource_len(pdev, BAR_1));if (!hw->ce4100_gbe_mdio_base_virt)goto err_mdio_io