百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

在30天自制操作系统上编写网卡驱动:遇到的主要困难总结

sinye56 2025-01-01 22:34 8 浏览 0 评论

在30天自制的操作系统上编写网卡驱动,对我来说,是件比较有挑战的事情。

资料难找,没有在30天自制操作系统上的驱动资料,现有的资料都是linux系统上的资料,或者windows系统上的资料,而30天自制操作系统本身是一个新的系统,是书上给出的一个操作系统样例,供大家学习的教学用的操作系统,所以,在这个操作系统上,还没对的驱动发开提供接口。比如linux操作系统或者是windows操作系统都对驱动开发做了支持的,其内核已经实现了对网卡的支持,然后驱动开发人员直接调用操作系统提供的函数去控制网卡就行了。

30天自制操作系统本身就没有对网卡的任何支持,更别说开发一些驱动开发的接口出来了。整体来说,比较有挑战。具体做的话,得先在操作系统内部把驱动运行起来,然后再把相关控制网卡的函数开放出来,供大家在此操作系统上开发驱动程序。

本来想看看linux系统的驱动程序是怎么写的,想移植过来,后来发现不可能直接抄linux系统的驱动程序,windows上的驱动程序,因为操作系统不同。

所以,要写网卡驱动,就得按照嵌入式开发的思路,在现有的30天自制的操作系统上,直接去控制网卡收发数据,网络协议解析等。

万事开头难,在自制操作系统上开发网卡驱动也是这样的。

首先的困难就是没有对网卡设备的发现程序。现在是在虚拟机上把30天自制操作系统运行起来的,虚拟机可能有虚拟的网卡,也可能没有。

后来通过对PCI总线的检测,发现了几个网卡的型号,也算解决了网卡的问题。用虚拟的网卡做实验。

然后紧接着一个问题就是:虚拟的网卡并没有将真实网卡的功能全部模拟。虚拟机只是模拟了真实网卡的部分功能,当你按照网卡的datasheet去操作虚拟网卡的时候,发现虚拟网卡没有反馈。

后来更换了虚拟机,发现有的虚拟机还是可以模拟出网卡的datasheet上的所有功能的。所以,是可以用虚拟机来开发网卡驱动的。

有了可以实验用的虚拟网卡,就可以开始着手开发网卡驱动了。按照datasheet以及嵌入式开发的一些例子,先尝试去读取和写入网卡芯片,然后再尝试让网卡发送数据,接收数据,然后再尝试去按照网络协议去组织数据发送出去,然后按照网络协议接收数据。这样一步一步的,步步为营。

想法虽然很好,但是真正开始开发时,又遇到一个问题:

我手头的虚拟机中的操作系统如何联网呢?

如果虚拟机里安装了一个windows,或者linux,那么我们很容易找到教程,去设置联网问题。现在我们手头的是一个还没有开发网卡驱动的操作系统,根本没有教程教怎么联网。
甚至如果是真实的主板,我们还能把网线插上,这就表示它联网了,等着开发网卡驱动程序就行了,
但是现在是虚拟机,怎么知道,怎么确认虚拟机的网线插上了?

不过以上问题最后都得到了解决。遇到问题是困难的,但是解决问题的那一瞬间就很幸福了。

我是如何找到网卡的

因为在虚拟机里安装linux操作系统后,linux操作系统是可以联网的。

所以,虚拟机本身肯定是带有网卡的,并且这个网卡也是能用的。

那么,如何把虚拟机上的网卡用起来? 查看到网卡的型号,然后搜索网卡芯片的类型,芯片有datasheet,datasheet上就详细说明了网卡如何使用。

不过在去控制网卡之前,要解决一个问题:如何让30自制操作系统找到这个网卡呢?

通过查找资料,我们发现,网卡一般都是通过PCI设备连接到CPU的。所以可以通过对PCI设备做个检索。

那么如何在30天自制操作系统上检索PCI设备呢?

我们的虚拟机的X86架构的CPU,这个CPU要检索PCI设备,只用通过IO端口就可以了,通过对某些固定的IO端口进行读写,就可以检索PCI设备了。


于是写程序去对相应端口进行检索,检索以后,发现,果然有网卡,并且型号为RTL8029.

这样,我就在30自制操作系统上找到网卡了。

后来发现,其实虚拟机启动的时候,是可以设置网卡的。


比如qemu可以通过如下命令设置网卡型号为ne2k_pci,即ne2000网卡,并且这个网卡是通过PCI与CPU相连的。所以,这样设置之后,我们就可以通过端口控制PCI,从而找到这个网卡了。

其实qemu上虚拟的网卡类型挺多的,如下:


其中e1000是qemu虚拟机默认的网卡,我们这里由于最先接触了TRL8029网卡,所以就选了与TRL8029网卡兼容的ne2k_pci。

除了可以把30天自制操作系统放到qemu虚拟机上,也可以放到parallels虚拟机上,parallels在配置界面上设置网卡型号:



可以看到,这两种虚拟机都实现了RTL8029网卡。


又是如何找到比较好用的虚拟网卡的

但是,找到虚拟网卡是第一步。

为什么这样说呢?

真正对网卡进行控制的时候,就发现qemu中的ne2k网卡,其实不能按照8029datasheet所提供的方式去控制:有些寄存器可以设置,有的不可以。这就是说:可能qemu虚拟网卡的功能不全,也可能8029网卡虽然与ne2k兼容,但是又是不同的,所以不能用控制8029方式去控制ne2k。可是,我现在就只有8029网卡的datasheet比较全面,ne2k的找到了零散几页。

这里展示一下找到虚拟网卡后,发现虚拟网卡功能不全的细节:

使用30自制操作系统自带的qemu.exe虚拟机,发现对网卡芯片8029的RCR,TCR,IMR等配置寄存器无法写入与读取,但对CR寄存器等却可以读取。这意味着qemu.exe虚拟机的网卡只能按照某种方式去接收,发送数据,但是真实的网卡是可以按照很多方式去接收发送数据的,我们做驱动开发也是要多种方式去验证的,所以qemu.exe上自带的8029网卡就无法使用了。

这让我的网卡驱动开发工作暂时停了下来。


发现还是不行,无法控制几个重要的配置寄存器去做回环测试。

可能虚拟机中的网卡没有将这些配置寄存器虚拟化。

那怎么办?

直接。。

后来有尝试了将我的qemu更新到最新的版本,发现有一些寄存器可以使用了,但是还是有若干个寄存器无法使用。

看来得去找一块真正的而不是虚拟的TRL-8029网卡了?


不过还是虚拟网卡比较方便些。
既然RTL8029不能操作,那么其他网卡型号能不能使用呢?比如e1000网卡。

于是我试着去找e1000网卡的datasheet,发现还是比较全面的,似乎也可以用。datasheet直接从Intel的官方,去下载就行了。不过操作办法有一些变化,之前很多专门控制8029的代码就不能用了。

通过 PCI配置发现,虚拟机默认的网卡是8086-100f的,这个网卡就是e1000网卡,那么这个网卡内部的芯片是什么呢?

http://pci-ids.ucw.cz/v2.2/pci.ids

在这个网站里,查到:


芯片是82545EM,那么就可以去找这个芯片的datasheet了。

其实在ubuntu上通过lspci -v命令,也可以查看到,网卡类型为e1000e时,其芯片是intel 的82574L

当指定了网卡类型为2k_pci后,就可以查看到TRL-8029了,如下图

可以看到,这个网卡的IO端口时C000,内存映射的位置是0xfeb80000,这里disabled的意思可能是指:当前网卡不支持内存映射访问,只支持IO端口。

不过,最终,我在paralles虚拟机上试了试它提供的RTL8029AS虚拟网卡,发现与我手头的datasheet是完全匹配的。原来在qemu上的那么不能操作的关键寄存器,现在都能够操作了。

这是一个关于qemu上关于虚拟网卡的处理过程,如果不是paralles上的虚拟网卡能用,我恐怕就要去详细看看qemu内部到底是如何虚拟化网卡的了:https://blog.csdn.net/dillanzhou/article/details/120169734

如何确定网卡驱动虚拟机有联网



既然,虚拟机中的ubuntu可以联网,那么虚拟机中的自制操作系统也是可以联网的。

其实,qemu联网也是很方便的,按如下命令来启动:

这里的参数-net user,虚拟机就会简历一个局域网,虚拟一个DHCP服务器来让虚拟机中操作系统获取IP地址。这种连接方式对于我们来说就够用了,因为我们写好网卡的发送程序后,就可以发送一些DHCP消息,去和DHCP服务器互动。

qemu还有一种联网方式是利用网桥,但是这个就需要安装在虚拟机内部的操作系统去连接这个网桥。但是,我们现在手头的30天自制操作系统还没有任何网络设备可用,所以,就不可能去连接这个网桥了。当然,这种方法连接后,虚拟机是可以连接到真实的局域网内部的,就是可以获取一个IP地址,这个IP地址是与运行虚拟机的电脑同一个局域网的。

通过网桥的连接方式就等网卡驱动开发好之后,再尝试做。

不过,由于qemu中的8029网卡我们操作不好,所以,自制操作系统通过qemu虚拟机的联网方式,我没有机会去验证。

在paralles中的8029网卡的寄存器可以被操作,也试了paralles中是否可以联网,发现是可以的,每收到一些网络信息,paralles右上角的网络信号会闪烁:


闪烁这个很鼓励人的。
当我们操作网卡尝试发送数据,但是接收多次方毫无反应,抓包软件也抓取不到,就会很失望:难道我们控制网卡发送数据的方式错了么?但是网卡的操作手册上就是这么写的呀?无从下手。
当看到这个标志有闪烁的时候,并且它与我们的发送动作是一致的:每次我按发送键,它就亮;我就基本可以确定,我确实有控制到网卡。那问题就出在我发出去的数据,可能格式不对,所以抓包软件抓不到。

只要确定我们能真的控制到网卡发送出去数据,那就好办了:

就是继续详细的查看到底格式错在哪里?再把DHCP协议,IP协议,ethernet协议所要求的字段,每个字段的长度,以及需要补零的数量搞搞清楚。

这就是paralles中这个蜘蛛网闪烁的意义。

这就相当于真实网卡的网线头子的那两个灯了:

所以,网线头子插口处的link灯和act灯,就是驱动开发人员看到希望的指路明灯。


当前的进度

实现了控制8029收发数据。

实现了按照DHCP协议去向DHCP服务器申请IP地址。其实实现DHCP,就是实现UDP,IP,ehternet协议。

实现了按照ARP协议去数据,然后解读ARP消息,回应APR消息,

后续准备:
1. 实现一下对ICMP消息的回应:即回应ping命令
2. 尝试利用IP协议传输较长的数据,即IP协议中的分段传输在重组。
3. 实现TCP协议,HTTP协议,尝试开发一个简单的网页服务器。不过这好像超出网卡驱动的范畴了,网页服务器还是不要在操作系统内部开发,要等网卡驱动接口通过0x40中断开放给APP后,开发一个网页服务器APP。
4. 因为当前这些驱动都是在操作系统内部写的,所以后续需要将内部驱动程序中的函数做成接口,通过0x40中断开放出去,这样也就支持了在30天操作系统上进行网络编程,利用这些接口,可以开发一个ping,开发一个arp,或者开发一个网页服务器。

相关推荐

CTO偷偷传我的系统性能优化十大绝招(万字干货)

上篇引言:取与舍软件设计开发某种意义上是“取”与“舍”的艺术。关于性能方面,就像建筑设计成抗震9度需要额外的成本一样,高性能软件系统也意味着更高的实现成本,有时候与其他质量属性甚至会冲突,比如安全性、...

提升效率!VMware虚拟机性能优化十大实用技巧

我40岁,干跨境婚恋中介的。为服务各国用户,常得弄英语、日语、俄语系统环境,VMware虚拟机帮了不少忙。用久了发现优化下性能,效率能更高。今儿就来聊聊优化技巧和同类软件。一、VMware虚拟...

低延迟场景下的性能优化实践

本文摘录自「全球C++及系统软件技术大会」ScottMeyers曾说到过,如果你不在乎性能,为什么要在C++这里,而不去隔壁的Pythonroom呢?今天我们就从“低延迟的概述”、“低延迟系...

Linux性能调优之内存负载调优的一些笔记

写在前面整理一些Linux内存调优的笔记,分享给小伙伴博文没有涉及的Demo,理论方法偏多,可以用作内存调优入门博文内容涉及:Linux内存管理的基本理论寻找内存泄露的进程内存交换空间调优不同方式的...

优化性能套路:带你战胜这只后段程序员的拦路虎

来源|极客时间《卖桃者说》作者|池建强编辑|成敏你好,这里是卖桃者说。今天给大家推荐一篇文章,来自倪朋飞老师的专栏《Linux性能优化实战》,文章主要讲的是优化性能的套路,这几乎是每个后端程序员...

SK海力士CXL优化解决方案已成功搭载于Linux:带宽提升30%,性能提升12%以上

SK海力士宣布,已将用于优化CXL(ComputeExpressLink)存储器运行的自研软件异构存储器软件开发套件(HMSDK)中主要功能成功搭载于全球最大的开源操作系统Linux上,不但提升了...

Linux内核优化:提升系统性能的秘诀

Linux内核优化:提升系统性能的艺术在深入Linux内核优化的世界之前,让我们先来理解一下内核优化的重要性。Linux内核是操作系统的核心,负责管理系统资源和控制硬件。一个经过精心优化的内核可以显著...

Linux系统性能优化:七个实战经验

Linux系统的性能是指操作系统完成任务的有效性、稳定性和响应速度。Linux系统管理员可能经常会遇到系统不稳定、响应速度慢等问题,例如在Linux上搭建了一个web服务,经常出现网页无法打开、打开速...

腾讯面试:linux内存性能优化总结

【1】内存映射Linux内核给每个进程都提供了一个独立且连续的虚拟地址空间,以便进程可以方便地访问虚拟内存;虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长的处理器,地址空间的范围也不同...

Linux文件系统性能调优《参数优化详解》

由于各种的I/O负载情形各异,Linux系统中文件系统的缺省配置一般来说都比较中庸,强调普遍适用性。然而在特定应用下,这种配置往往在I/O性能方面不能达到最优。因此,如果应用对I/O性能要求较高,除...

Nginx 性能优化(吐血总结)

一、性能优化考虑点当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题,需要从以下几个方面进行探讨当前系统结构瓶颈了解业务模式性能与安全1、当前系统结构瓶颈首先需要...

Linux问题分析与性能优化

排查顺序整体情况:top/htop/atop命令查看进程/线程、CPU、内存使用情况,CPU使用情况;dstat2查看CPU、磁盘IO、网络IO、换页、中断、切换,系统I/O状态;vmstat2查...

大神级产品:手机装 Linux 运行 Docker 如此简单

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:灵昱Termux作为一个强大的Android终端模拟器,能够运行多种Linux环境。然而,直接在Termux上运行Docker并不可行,需要...

新手必须掌握的Linux命令

Shell就是终端程序的统称,它充当了人与内核(硬件)之间的翻译官,用户把一些命令“告诉”终端程序,它就会调用相应的程序服务去完成某些工作。现在包括红帽系统在内的许多主流Linux系统默认使用的终端是...

Linux 系统常用的 30 个系统环境变量全解析

在Linux系统中,环境变量起着至关重要的作用,它们犹如隐藏在系统背后的“魔法指令”,掌控着诸多程序的运行路径、配置信息等关键要素。尤其在shell脚本编写时,巧妙运用环境变量,能让脚本如虎...

取消回复欢迎 发表评论: