日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
深入探究Linux下int86BIOS操作(linuxint86bios)

在計算機領(lǐng)域,BIOS(基本輸入輸出系統(tǒng))是指固化在計算機主板上的一組程序,用于在計算機啟動期間執(zhí)行硬件初始化和自主檢查,以確保計算機硬件能夠正常工作。在PC架構(gòu)中,BIOS通常具有訪問低級硬件和設(shè)置計算機配置的能力。在Linux操作系統(tǒng)下,我們可以通過int86函數(shù)來調(diào)用BIOS的功能,從而實現(xiàn)對硬件的訪問和配置。

利辛網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,利辛網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為利辛超過千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個售后服務(wù)好的利辛做網(wǎng)站的公司定做!

int86函數(shù)的定義如下:

“`c

int int86(int intno, union REGS *in, union REGS *out);

“`

其中,intno為BIOS的中斷號;in為輸入?yún)?shù)的寄存器,包括AX、BX、CX、DX等;out為輸出參數(shù)的寄存器。

在Linux下使用int86函數(shù)需要注意以下幾點:

1. int86函數(shù)需要使用內(nèi)核支持的__KERNEL__宏定義來編譯,否則會出現(xiàn)編譯錯誤。

2. int86函數(shù)的寄存器結(jié)構(gòu)體REGS定義在linux/a/syscalls.h頭文件中。

3. 在Linux下,BIOS的中斷號需要加上0x80來調(diào)用,即INT 0x80。

下面我們將針對常見的BIOS操作進行深入探究。

1.顯示字符串

在BIOS中,顯示字符串的中斷號為0x10,我們可以通過int86函數(shù)調(diào)用BIOS來顯示字符串。

下面是顯示字符串的代碼實現(xiàn):

“`c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

typedef unsigned char byte;

typedef unsigned short word;

struct videoinfo {

byte mode;

byte page;

word col;

word row;

byte attr;

byte ch;

};

struct videoinfo SavePara2[2];

struct videoinfo SavePara[1];

int mn()

{

char *str = “Hello World!”; // 要顯示的字符串

int str_len = strlen(str); // 字符串長度

__a__ __volatile__(

“movw $0x0003,%%ax\n\t”

“int $0x10\n\t”

:

:

: “%eax”

); // 將顯示模式設(shè)置為80×25,00為文本模式,02和03為CGA模式

__a__ __volatile__(

“movw $0x0000,%%ax\n\t”

“movw $0x0000,%%bx\n\t”

“movw $0x0007,%%cx\n\t”

“movw $0x0000,%%dx\n\t”

“int $0x10\n\t”

:

:

: “%eax”,”%ebx”,”%ecx”,”%edx”

); // 保存當前顯示參數(shù)

__a__ __volatile__(

“movw $0x0000,%%ax\n\t”

“movw %%ax,%%es\n\t”

“movw $0x0000,%%bx\n\t”

“movw $0x0000,%%dx\n\t”

“movw %2,%%cx\n\t”

“movw $0x0009,%%ah\n\t”

“int $0x10\n\t”

:

: “a” (0x0e00), “b” (0x0000), “c” (str_len), “d” ((int)str)

:

); // 在文本模式下,將字符串輸出到屏幕

__a__ __volatile__(

“movw $0x0000,%%ax\n\t”

“movw $0x0000,%%bx\n\t”

“movw $0x0007,%%cx\n\t”

“movw $0x0000,%%dx\n\t”

“int $0x10\n\t”

:

:

: “%eax”,”%ebx”,”%ecx”,”%edx”

); // 恢復(fù)原來的顯示參數(shù)

}

“`

上述代碼中,我們首先將顯示模式設(shè)置為文本模式(80×25),然后保存當前的顯示參數(shù),接著在屏幕上顯示字符串,最后恢復(fù)原來的顯示參數(shù)。

2.讀寫磁盤

BIOS提供了讀寫磁盤的功能,其中讀磁盤操作的中斷號為0x13,寫磁盤操作的中斷號為0x19。

下面是讀寫磁盤的代碼實現(xiàn):

“`c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

typedef unsigned char byte;

typedef unsigned short word;

struct diskinfo {

byte head;

byte sect_cyl;

byte cyl;

byte sect;

void *buf;

};

struct diskinfo SavePara[1];

struct diskinfo SavePara2[1];

int mn()

{

short count = 1; // 讀取扇區(qū)的個數(shù)

byte sector = 1; // 起始扇區(qū)

byte head = 0; // 磁頭號

byte cyl = 0; // 柱面號

byte feature = 0x80; // 定義控制字節(jié),指定使用LBA模式

byte read_cmd = 0x42; // 定義讀取命令號

byte drive_id = 0x80; // 定義磁盤驅(qū)動器號,80h表示0號磁盤驅(qū)動器

char buf[512]; // 存放讀取到的數(shù)據(jù)

__a__ __volatile__(

“movw $0x0000,%%bx\n\t”

“movw $0x0000,%%es\n\t”

“movw $0x0000,%%di\n\t”

“int $0x13\n\t”

:

:

:”%eax”,”%ebx”

); // 保存磁盤參數(shù)

__a__ __volatile__(

“movw $0x0000,%%di\n\t”

“movw $0x0000,%%es\n\t”

“movw $0x0000,%%bx\n\t”

“movw %4,%%cx\n\t”

“movb %3,%%cl\n\t”

“movb %2,%%dh\n\t”

“movb %1,%%ch\n\t”

“movb %0,%%ah\n\t”

“movb %5,%%dl\n\t”

“int $0x13\n\t”

:

:”m”(read_cmd), “m”(feature),”m”(head),”m”(sector),”m”(count),”m”(drive_id),”d”((int)buf)

:”%eax”,”%ebx”

); // 讀取磁盤

__a__ __volatile__(

“movw $0x0000,%%bx\n\t”

“movw $0x0000,%%es\n\t”

“movw $0x0000,%%di\n\t”

“int $0x13\n\t”

:

:

:”%eax”,”%ebx”

); // 恢復(fù)原來的磁盤參數(shù)

}

“`

上述代碼中,我們首先保存當前的磁盤參數(shù),然后通過int86函數(shù)調(diào)用BIOS,讀取指定位置的磁盤數(shù)據(jù),最后恢復(fù)原來的磁盤參數(shù)。

3.設(shè)置中斷向量

BIOS為每個中斷提供了一個中斷向量,其中每個中斷向量的尋址方式為中斷號*4,比如中斷號為0x10,那么對應(yīng)的中斷向量地址就是0x40。

下面是設(shè)置中斷向量的代碼實現(xiàn):

“`c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

typedef unsigned char byte;

typedef unsigned short word;

void set_intvect(byte intno, void (*handler)(void));

void int_timer(void);

void set_intvect(byte intno, void (*handler)(void))

{

word offset = (word)handler; // 中斷處理程序的段內(nèi)偏移

word segment = (word)handler >> 16; // 中斷處理程序的段地址

*(word *)(intno * 4) = offset;

*(word *)(intno * 4 + 2) = segment; // 設(shè)置中斷向量

}

void int_timer(void)

{

printf(“Timer Interrupt!\n”);

__a__ __volatile__(

“pushl %eax\n\t”

“pushl %ebx\n\t”

“movw $0x0028,%%ax\n\t”

“movw %%ax,%%ds\n\t”

“movw %%ax,%%es\n\t”

“movw $0x0000,%%bx\n\t”

“movb $0x20,%%al\n\t”

“outb %%al,$0x20\n\t”

“popl %ebx\n\t”

“popl %eax\n\t”

“iret\n\t”

:

:

:

); // 定義中斷處理程序

}

int mn()

{

set_intvect(0x08, int_timer); // 設(shè)置中斷向量

while(1)

{

__a__ __volatile__(

“hlt\n\t”

:

:

:

); // 等待中斷

}

}

“`

上述代碼中,我們首先定義了一個中斷處理程序,用于處理時鐘中斷。然后通過set_intvect函數(shù)設(shè)置中斷向量,即將中斷號為0x08的中斷向量設(shè)置為int_timer函數(shù)。最后我們無限循環(huán)等待時鐘中斷的到來,以確保中斷處理程序能夠被正確地執(zhí)行。

成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián)為您提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁設(shè)計及定制高端網(wǎng)站建設(shè)服務(wù)!

可以通過BIOS把顯示模式改為VGA圖形模式嗎

可以。中斷10H,即Video BIOS,負責(zé)處理文本模式和圖形模式之間的轉(zhuǎn)換。當你所運行的程序要進行文本模式和圖形模式之間的相互轉(zhuǎn)換時(即使該程序是Microsoft Windows),就需要通過Video BIOS來實現(xiàn)這種轉(zhuǎn)換。每一種不同的設(shè)置都被稱作一種顯示模式。

要改變顯示模式,你必須通過int 10H服務(wù)來調(diào)用Video BIOS。這就是說,你必須向中斷10H的中斷處理程序發(fā)出中斷請求。除中斷號不同之外,這與實現(xiàn)DOS調(diào)用(int 21H)沒有什么區(qū)別。下面的一段程序通過調(diào)用Video BIOS函數(shù)0,先從標準文本模式(模式3)切換到一個由命令行輸入的模式號,然后再切換回來:

# include

# include

main(int argc, char * * argv)

{

union REGS regs;

int mode;

/ * accept Mode number in hex * /

sscanf (argv , ” %x” , &mode) ;

regs. h. ah = 0;/* AH = 0 means “change display mode” */

regs.h.al = (char)mode; /* AL = ??, where ?? is the Mode number *

regs. x. bx = 0;/* Page number, usually zero */

int86(0xl0, ?s, ?s); /* Call the BIOS (intlO) * /

printf(“Mode 0x%X now active\n” , mode);

printf (“Press any key to return. . . “) ;

getch();

regs. h. al = 3;/ * return to Mode 3 * /

int86(0xl0, ?s, ?s);

}

有一個有趣的特點并沒有在這個程序中表現(xiàn)出來,即該程序可以在不清屏的情況下改變顯示模式。在某些場合,這一特點極為有用。要想改變顯示模式,而又不影響屏幕內(nèi)容,只需把存放在AI.寄存器中的顯示模式值和80H或一下。例如,如果你要切換到模式13H,你只需把93H存入AL中,而程序中其余的代碼可以保持不變。

今天,在VESA Video BIOS標準中已經(jīng)加入了VGA卡對擴充顯示模式(見下文中的補充說明)的支持。然而,需要有一個新的“改變顯示模式”函數(shù)來支持這些擴充模式。按照VESA標準,在切換VESA模式時,應(yīng)該使用函數(shù)4FH,而不是前文例子中的函數(shù)O。下面的程序改進了前文中的例子,以切換VESA模式:

# include

#include

main(int argc, char * * argv)

{

union REGS regs;

int mode;

/ * accept Mode number in hex * /

sscanf (argv, ” %x” , &mode);

regs. x. ax = 0x4F02;/* change display mode * /

regs. x. bx = (short )mode; / * three-digit mode number * /

int86(0x10, ?s, ?s); /* Call the BIOS (intlO) * /

if(regs.h.al !=0x4F){

printf(“VESA modes NOT supported! \n” );

}

else {

printf(“Mode Ox%X now active\n” , mode);

printf (“Press any key to return. . . ” ) ;

getch() ;

}

regs. h. al = 3;/ * return to Mode 3 * /

int86(0x10,?s, ?s) ;

}

注意,在切換VESA模式時,不能通過把模式號和80H或一下來達到不清屏的目的。但是。只要把原來兩位的(十六進制)模式號的更高位往前移一位,就得到了VESA模式號(所有VESA模式號的長度都是三位(十六進制),見下文中的補充說明)。因此,為了切換到VESA模式101H并且保留屏幕上的內(nèi)容,你只需把VESA模式號換為901H。

關(guān)于顯示模式的補充說明:

IBM推出了一種顯示模式標準,該標準試圖定義所有可能會用到的顯示模式,其中包括所有可能的像素層次(顏色的數(shù)目)。因此,IBM創(chuàng)建了19種顯示模式(從OH到13H)。表14.8a給出了這種顯示模式標準。

14.8a 標準顯示模式

模式(H)分辨率圖形/文本顏色

X 文本 單色

X 文本 16

X 文本 單色

X 文本 16

X 圖形 4

X 圖形 4級灰度

X 圖形 單色

X 文本 單色

X 圖形 16

X 圖形 16

Ax圖形 4

B 保留給EC-A BIOS使用

C 保留給EGA BIOS使用

D×圖形 16

E×圖形 16

F×圖形 單色

×圖形 4

×圖形 單色

×圖形 16

×圖形 256

那么,你見過其中的某些模式嗎?模式3是80×25彩色文本模式,也就是PC機上電時你所看到的模式。當你把”VGA”(隨Windows提供的一個驅(qū)動程序)選為Microsoft Windows3.x的驅(qū)動程序時,你所看到的就是模式12(H)。注意,上表中并沒有一種顏色多于256色或分辨率高于640×480的模式。多年以來,模式4,9和D一直是DOS游戲開發(fā)者喜歡用的模式,它們擁有“高”達320×200的分辨率和足夠的顏色(4或16種),足以顯示一些“象樣”的圖形。所有流行的動畫游戲幾乎都使用模式13,例如DOOM(一代和二代),id軟件公司的new Heretic,Apogee公司的Rise of the Triad,Interplay公司的Descent,等等。實際上,許多動畫游戲在VGA卡上耍了個小花招,即把模式13的分辨率改為320×這種模式被稱為模式x,它有更多的內(nèi)存頁??梢蕴岣邎D形質(zhì)量和顯示速度。

那么,其它一些常見的顯示模式又是從哪里來的呢?它們是由VGA卡的制造商提供的。這些你可能已經(jīng)熟悉的顯示模式來自各種各樣的渠道,但不管它們來自何處,VGA卡的制造商們都把它們加到了自己的VGA卡中,以增加這些VGA卡的價值。這些模式通常被稱為擴充顯示模式(extended display mode)。由于競爭和資本積累的原因,VGA卡的制造商們逐步轉(zhuǎn)向了這些更高級的顯示模式。有人還試過其它一些顯示模式(聽說過1152×900嗎?),但并不象上述模式那樣受歡迎。

那么。什么是VESA呢?它與VGA卡有什么關(guān)系呢?盡管VGA卡的制造商們都選擇了支持同樣的一組顯示模式(包括擴充模式),但他們都按自己的專用方式去實現(xiàn)其中的擴充模式,而游戲廠商和其它軟件廠商不得不去支持市場上每一種VGA卡的每一種專用方式。因此,一些制造商和其它方面的一些代表一起組成了一個委員會,以盡可能地使這些卡的設(shè)置和編程標準化,這個委員會就是VESA(Video Electronic Standards Association)。VESA委員會采用了一種擴充顯示模式的標準,從而使軟件可以通過普通的BIOS調(diào)用來設(shè)置和初始化所有符合該標準的VGA卡?;旧峡梢赃@樣說,在美國出售的所有的VGA卡都支持某種VESA標準。

所有的VESA模式(即VESA標準所包含的那些顯示模式)都采用寬度為9位(bit)的模式號,而不是標準模式的8位(hit)模式號。使用了9位(bit)的模式號后,就可以用三位十六進制數(shù)來表示VESA模式了,而IBM標準模式只能用兩位十六進制數(shù)(在表14.8a中,從0到13H)來表示,這樣就避免了模式號的沖突。因此,所有的VESA模式號都大于100H。VESA模式是這樣起作用的:假設(shè)你想讓你的VGA卡以1024×768和256色這樣的模式顯示,而這種模式就是VESA模式105,因此你要用模式號105作一次BIOS調(diào)用。Video BIOS(有時叫做VESA BIOS)會把VESA模式號翻譯成內(nèi)部專用號,以完成實際的模式切換工作。VGA卡的制造商們在每一塊VGA卡上都提供了一種可以完成上述翻譯工作的Video BIOS,因此你只需要搞清楚VESA模式號就行了。表14.8b列出了最新的VESA顯示模式(VESA是一個不斷發(fā)展的標準。)

表14.8b VESA顯示模式

——

分辨率 顏色VESA模式

——

640X 100

640X 101

640X 110

640X 111

640X 16. 7M

800X 102

800X 103

800X 113

800X 114

800X 16. 7M

1024X 104

1024X 105

1024X 116

1024X 117

1024X 16. 7M

1280X 106

1280X 107

1280X 119

1280X 11A

1280X 16. 7MB

linux int86 bios的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于linux int86 bios,深入探究Linux下int86 BIOS操作,可以通過BIOS把顯示模式改為VGA圖形模式嗎的信息別忘了在本站進行查找喔。

香港服務(wù)器選創(chuàng)新互聯(lián),香港虛擬主機被稱為香港虛擬空間/香港網(wǎng)站空間,或者簡稱香港主機/香港空間。香港虛擬主機特點是免備案空間開通就用, 創(chuàng)新互聯(lián)香港主機精選cn2+bgp線路訪問快、穩(wěn)定!


分享標題:深入探究Linux下int86BIOS操作(linuxint86bios)
分享鏈接:http://www.dlmjj.cn/article/dpgeopg.html