驅動程序一般指的是設備驅動程序(Device Driver),是一種使計算機和外設設備之間通信的特殊程序,可以理解為是直接工作在各種硬件設備上的軟件或接口,其“驅動”這個名稱也十分形象的指明了它的功能。因此通過驅動程序,各種硬件設備才能正常進行,達到定義的工作效果。
從理論上講,所有的硬件設備都需要安裝相應的驅動程序才能正常工作。但是像CPU、內存、主板、軟驅、顯示器,PS/2鍵鼠等一些設備卻并不需要安裝驅動程序也可以正常運行,而顯卡,聲卡、網卡、打印機等設備卻一定要安裝驅動程序,否則便無法正常工作,這又是怎么回事呢?
原因是CPU、主板、內存、硬盤、顯示器、鍵鼠這些硬件對一臺電腦本身來說是必需的組成部分,所以早期的設計人員講這些硬件列為BIOS能直接支持的硬件。也就是這些硬件集成在主板之后可以被BIOS和操作系統直接支持,不用再安裝驅動程序,可以看做BIOS就是一種驅動程序,但是對于其他的外設硬件,則必須要安裝驅動程序,這樣才能使電腦與設備之間進行通信工作。
那么認識到驅動程序是非常重要的,怎么檢測我們需要哪些驅動程序呢?又怎么來獲取呢?又怎么驗證安裝是否成功呢?現在很多軟件公司其實對這些問題的解決方案已經做得非常成熟和標準的,包括微軟官方的win10系統已經對這方面進行集成完善,沒有早前xp,win7會出現的無驅動或者驅動不完善情況。
驅動程序目前主要的有驅動精靈,驅動人生、驅動總裁、萬能驅動助手、360驅動大師等,只要獲取到這個安裝驅動的軟件,然后運行就會檢測出我們電腦當前缺失的驅動有哪些,并且直接可以一鍵安裝缺失程序,安裝完成之后會提示是否成功,所以比較簡單。
這里我給大家介紹一下用萬能驅動助手來安裝,步驟如下
第一步:首先將萬能驅動助手下載到本地,雙擊打開軟件程序
第二步:勾選需要安裝的驅動程序
這里解釋下專用和公版,簡義即專用為專門針對此電腦進行的一種程序設計,適應性強。公版為廠商對一系列芯片類型設計的程序,兼容性強但適應性差。
第三步:選擇驅動解壓的位置以及安裝程序包處理的方式,然后點擊安裝
第四步:安裝完成,可以通過設備管理器檢驗我們的驅動程序是否成功或者良好狀態
或者可以通過硬件檢測工具EVEREST查看,EVEREST Ultimate Edition是一個測試軟硬件系統信息的工具,用戶可以詳細地查看電腦的各項硬件信息是否有問題,讓用戶的電腦運行更高效。
大家可以看到我的電腦各個驅動是良好的,所以你的呢?趕緊去看看吧!
如果在上述的驅動軟件安裝某個驅動一直失敗,那么有兩種可能,第一個是驅動軟件里的驅動版本根本不適應你的電腦型號,那么可以到該電腦官網的服務支持里具體查找,下載安裝會解決這種問題。第二個是該系統存在問題,建議換個系統安裝。
感謝觀看,下期再見。
原創作者:數據恢復小王,維護版權所有,禁止盜用
們都知道顯卡不裝驅動程序顯卡不能正常工作,在計算機系統中,硬件設備的操作和控制需要通過驅動程序來實現,驅動程序在操作系統和硬件設備之間起到橋梁連接的作用。本文將從為何需要安裝驅動程序開始,以Linux 系統中的 LED 驅動為例,逐步解釋驅動程序的本質,以及操作系統是如何調用到驅動程序,并展示編寫 ARM Linux LED 驅動的具體步驟和代碼。
計算機系統中存在著各種不同類型的硬件設備,例如打印機、顯示器、網絡接口卡等。這些設備通常由不同的制造商生產,因而其工作原理和通信協議也可能各不相同。為了實現操作系統與這些硬件設備的良好協作,需要一個中間層來處理硬件細節,提供一個標準的接口供操作系統和應用程序使用,這就是驅動程序的作用。應用程序通過操作系統調用到驅動程序,從而實現操控硬件,所以驅動程序中必然是操作硬件的具體細節代碼。
驅動程序本質上是一段軟件代碼,它建立了硬件設備與操作系統之間的橋梁。通過這個橋梁,操作系統可以通過通用的接口調用,而無需關心硬件設備的底層細節。驅動程序通過向操作系統提供標準的命令和函數,使得應用程序可以方便地與硬件設備進行交互。
這里我們以Linux系統設備驅動為例來說明一下。
在 Linux 系統中,驅動程序是內核的一部分,它們以模塊的形式存在。內核模塊是一種可以在運行時加載和卸載的代碼,允許將驅動程序動態地添加到內核中。Linux 驅動程序通常由一系列的回調函數組成,這些函數定義了驅動程序與內核之間的接口。
驅動程序在Linux系統中的位置
上圖中綠色部分就是驅動程序,我們可以看到,應用程序Application通過調用操作系統內核提供的系統調用接口(System call Interface),系統調用通過虛擬文件系統(VFS)提供的設備文件找到對應的驅動程序模塊,從而調用到驅動程序中對應的操作函數,從而實現操控硬件。
詳細open過程
這里我們以Linux字符設備為例,來詳細說明一下應用程序是如何訪問到驅動程序的。
如上圖,應用程序比如要實現打開某一個字符設備的操作,那應用程序中必須調用系統調用open函數,并提供設備文/dev/led。
1.open系統調用通過字符設備文件(/dev/led)找到inode
2.根據inode的信息創建file
3.根據inode中成員i_mode 確定設備類型 c(mknod創建inode,并將c主次設備號,文件名等信息存入到inode中)
4.根據inode中成員i_rdev 確定設備號,根據設備號可以找到 cdev結構體(內核中好多字符設備,每個字符設備對應一個cdev結構體)
5.將找到的cdev結構體指針存入 inode成員i_cdev中
6.將找到的cdev 中 成員 ops(file_operation) 地址給 file中成員f_ops
7.open 根據 file中的 f_ops找到驅動中的file_opertions,這樣就可以調用其中對應的open
所以驅動是以模塊的形式放入內核,然后實現file_operation中對應的這些接口來為上層應用調用到。驅動中需要實現的這些接口函數代碼就是操作硬件的細節代碼,細節代碼和硬件相關性很大。
記住一句話:應用程序是通過主設備號對應上驅動程序的。
Linux 應用程序通過系統調用接口與設備驅動程序進行通信。對于字符設備,常見的系統調用包括 open、write、read、ioctl、close 等。應用程序通過這些系統調用向設備驅動發出命令,實現對硬件設備的控制。
以下是一個我寫的完整的可運行的led驅動代碼。如果你沒學過linux驅動肯定看不懂全部代碼,不過沒關系,我只是借用這個代碼來講解一下驅動程序到底是要寫什么。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/mm.h>
#include <linux/io.h>
#define LED_ON _IO('C',0)
#define LED_OFF _IO('C',1)
#define GPX2CON 0x11000c40
#define GPX2DAT 0x11000c44
static int led_major=0;
struct led_dev{
struct cdev led_cdev;
dev_t devnum;
volatile unsigned int *gpx2con;
volatile unsigned int *gpx2dat;
}led_dev;
int led_open(struct inode * inodep, struct file *filep)
{
printk("led device opened !\n");
return 0;
}
int led_close(struct inode *inodep, struct file *filep)
{
printk("led device closed\n");
return 0;
}
ssize_t led_read(struct file *filep, char __user *ubuf, size_t size, loff_t *loff)
{
return 0;
}
ssize_t led_write(struct file *filep , const char __user *ubuf, size_t size, loff_t *loff)
{
return 0;
}
long led_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
switch(cmd){
case LED_ON:
iowrite32(ioread32(led_dev.gpx2dat) | (0x1 << 7), led_dev.gpx2dat);
break;
case LED_OFF:
iowrite32(ioread32(led_dev.gpx2dat) & (~(0x1 << 7)), led_dev.gpx2dat);
break;
default:
return -EINVAL;
}
return 0;
}
struct file_operations led_ops={
.owner=THIS_MODULE,
.open=led_open,
.release=led_close,
.read=led_read,
.write=led_write,
.unlocked_ioctl=led_ioctl
};
static int led_init(void)
{
int result;
//1.alloc device num
result=alloc_chrdev_region(&(led_dev.devnum),0,1,"led");
if(result < 0){
printk("chrdev device num alloc error\n");
return result;
}
led_major=MAJOR(led_dev.devnum);
printk("led major=%d\n",led_major);
//2.init cdev
cdev_init(&led_dev.led_cdev,&led_ops);
//3.add cdev
result=cdev_add(&led_dev.led_cdev,led_dev.devnum,1);
if(result < 0){
printk("cdev add error\n");
goto err1;
}
//4.map led register
led_dev.gpx2con=ioremap(GPX2CON, sizeof(int));
if(led_dev.gpx2con==NULL){
printk("led device gpx2con remap failed!\n");
goto err2;
}
led_dev.gpx2dat=ioremap(GPX2DAT, sizeof(int));
if(led_dev.gpx2dat==NULL){
printk("led device gpx2dat ioremap failed!\n");
goto err3;
}
//5.setting GPX2_7 pin output mode
iowrite32((ioread32(led_dev.gpx2con) & (~(0xf << 28))) | ((0x1 << 28)), led_dev.gpx2con);
iowrite32(ioread32(led_dev.gpx2dat) & (~(0x1 << 7)), led_dev.gpx2dat);
printk("led driver module init ok!\n");
return 0;
err3:
iounmap(led_dev.gpx2con);
err2:
cdev_del(&led_dev.led_cdev);
err1:
unregister_chrdev_region(led_dev.devnum,1);
return result;
}
static void led_exit(void)
{
//1.del cdev
cdev_del(&led_dev.led_cdev);
//2.release chrdev device num
unregister_chrdev_region(led_dev.devnum,1);
printk("led driver module exit!\n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("albert@gmail.com");
MODULE_DESCRIPTION("the Driver for led device");
module_init(led_init);
module_exit(led_exit);
重點在file_operations這個結構體,可以看到我在驅動中實現了led_open,led_close,led_write和led_ioctl五個具體操作接口,上層就是通過這個5個指針調到驅動中這五個函數。
file_operations
具體實現led燈亮滅的代碼就在led_ioctl這個函數,這個不同硬件電路具體代碼不一樣,
ioctl細節代碼
但是可以看到其實就是操作寄存器,設置寄存器對應位高低電平就能實現燈亮滅。操作硬件就是操作寄存器這是通用底層邏輯。
我們來看一下驅動程序對應的應用層測試代碼。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define LED_ON _IO('C',0)
#define LED_OFF _IO('C',1)
int main(int argc, char **argv)
{
int fd=open(argv[1], O_RDWR);
if(-1==fd){
printf("open device error");
return -1;
}
while(1){
ioctl(fd, LED_ON);
sleep(2);
ioctl(fd, LED_OFF);
sleep(2);
}
close(fd);
return 0;
}
應用層代碼就是調用ioctl系統調用來實現等的2秒閃爍功能。應用層這里通過調用ioctl可以通過文件系統調到驅動程序中注冊的file_operations中unlocked_ioctl指針指向的led_ioctl函數,從而實現led的亮滅。
后續持續更新系列高質量文章,碼字不易,覺得寫的不錯歡迎關注、點贊、收藏以及提問。
時我們使用電腦時,偶爾桌面上會彈出“更新驅動”的彈窗,比如顯卡驅動等相關硬件程序,那么我們應該經常更新驅動嗎?如果更新驅動怎樣才能保持系統程序的穩定性?下面小A給大家講解一下該如何科學更新電腦的驅動,一起來看看吧。
圖片來源:官網截圖
首先小A先給大家科普一下“什么是驅動”?所謂驅動是指電腦里的設備驅動程序,它是硬件廠商根據系統編寫的配置文件,其中包含設備的硬件信息,用來傳遞硬件功能、傳達系統指令,如果沒有驅動程序存在,那么電腦系統就無法控制硬件正常工作。
硬件驅動程序的更新主要是改善性能,或者針對某些軟件、游戲等做優化適配。通常電腦里的驅動程序都會在發布新版本時候,為用戶提供詳細的描述信息,包括變動日志等內容,大家可以通過閱讀這些內容了解新版驅動有哪些改動,解決了什么問題,再決定是否要升級驅動便可。
圖片來源:官網截圖
不過如果你的電腦本身系統運行很流暢,小A建議不要頻繁更新驅動,因為有些新的驅動版本在兼容性方面不夠完善,更新后反而容易出現問題,不妨等穩定的版本出來后再做更新。而且對于一些比較老的硬件,老版本驅動已經足夠成熟,新驅動更多的是針對較新的產品進行完善,因此給老產品安裝最新驅動可能沒有什么明顯效果,甚至會因為不同時代產品較大的差異導致老硬件運行新驅動產生各種問題。
這里小A建議大家從以下幾種方法來進行更新驅動:
如果你購買的是筆記本/臺式機整機,那么大家可以直接去品牌官方網站下載驅動,比如進入“華碩官網”,進入“驅動下載”菜單,然后根據你選擇的機型,尋找相關驅動,當然也可以自行輸入產品型號來找到相關硬件驅動。
圖片來源:官網截圖
單一配件設備的驅動更新,則可以去配件品牌的官方網站下載,就拿顯卡程序更新來說,通常顯卡分為A卡和N卡,前者屬于AMD,后者屬于NVIDIA,大家如果需要更新,前往相應官網找到自己的顯卡型號,更新即可。
圖片來源:官網截圖
大家可以在電腦里找到“設備管理器”并右擊該設備,通過聯網“更新驅動程序軟件”進行安裝。
圖片來源:Windows系統截圖
好啦,關于更新電腦驅動以及更新驅動方法就給大家介紹到這里了,你明白了嗎~~