[OS64][033] 源碼閱讀:程序8-2 物理機(jī)器 CPUID 查詢處理器固件信息

學(xué)習(xí)筆記

使用教材(配書源碼以及使用方法)
《一個(gè)64位操作系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)》
http://www.ituring.com.cn/book/2450
http://www.reibang.com/p/28f9713a9171

源碼結(jié)構(gòu)

  • 配書代碼包 :第8章 \ 程序 \ 程序8-2

實(shí)驗(yàn)操作

1撩满、虛擬機(jī):生成boot.bin 棠绘、loader.bin以及kernel.bin 并復(fù)制到U盤

[anno@localhost 32MB-bootloader]$ 
sudo dd if=boot.bin of=/dev/sdb bs=512 count=1 conv=notrunc

[anno@localhost 物理平臺(tái)]$ cd kernel
[anno@localhost kernel]$ make
gcc -E head.S > head.s
as --64 -o head.o head.s
gcc -E entry.S > entry.s
as --64 -o entry.o entry.s
gcc  -mcmodel=large -fno-builtin -m64 -c main.c
gcc  -mcmodel=large -fno-builtin -m64 -c printk.c
gcc  -mcmodel=large -fno-builtin -m64 -c trap.c
gcc  -mcmodel=large -fno-builtin -m64 -c memory.c
gcc  -mcmodel=large -fno-builtin -m64 -c interrupt.c
gcc  -mcmodel=large -fno-builtin -m64 -c task.c 
gcc  -mcmodel=large -fno-builtin -m64 -c cpu.c
ld -b elf64-x86-64 -z muldefs -o system head.o entry.o main.o printk.o trap.o memory.o interrupt.o task.o cpu.o -T Kernel.lds 
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin

根據(jù)自己使用的U盤网严,修改bootloader部分源碼的方法參見
[OS64][031]實(shí)驗(yàn)操作:程序7-3 移植到物理平臺(tái) U盤啟動(dòng)
http://www.reibang.com/p/a84b45ae3219

  • 其實(shí)程序8-2程序7-3使用的bootloader代碼是一致的胸墙,如果在程序7-3的實(shí)驗(yàn)中已經(jīng)按照自己的U盤規(guī)格制作好了boot.bin猾骡、loader.bin牢贸,可以直接拿來用了

2子漩、物理機(jī)器:插上U盤阿弃,顯示運(yùn)行畫面

程序8-2 運(yùn)行畫面

源碼閱讀

get_cpuid 用于獲取處理器固件信息

CPUID指令將通過EAX寄存器輸入查詢的主功能號(hào),如果有需要缀雳,則再向ECX寄存器輸入查詢的子功能號(hào)渡嚣。
當(dāng)這條匯編指令執(zhí)行結(jié)束后,查詢的返回值將保存在EAX肥印、EBX识椰、ECX和EDX寄存器

代碼清單8-4 第8章\程序\程序8-2\物理平臺(tái)\kernel\cpu.h

inline void get_cpuid(unsigned int Mop,
    unsigned int Sop,
    unsigned int * a,
    unsigned int * b,
    unsigned int * c,
    unsigned int * d)
{
    __asm__ __volatile__    (    "cpuid    \n\t"
                                 :"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d)
                                 :"0"(Mop),"2"(Sop)
                            );
}

  • CPUID匯編指令封裝成get_cpuid函數(shù)
  • MopSop參數(shù)用于向CPUID指令傳遞主功能號(hào)子功能號(hào)
  • 將查詢的返回值保存到指針變量a、b深碱、c和d指向的內(nèi)存

init_cpu() 中調(diào)用 get_cpuid(...)

void init_cpu(void)
{
    int i,j;
    unsigned int CpuFacName[4] = {0,0,0,0};
    char    FactoryName[17] = {0};

    //vendor_string
    get_cpuid(0,0,&CpuFacName[0],&CpuFacName[1],&CpuFacName[2],&CpuFacName[3]);

    *(unsigned int*)&FactoryName[0] = CpuFacName[1];

    *(unsigned int*)&FactoryName[4] = CpuFacName[3];

    *(unsigned int*)&FactoryName[8] = CpuFacName[2];    

    FactoryName[12] = '\0';
    color_printk(YELLOW,BLACK,"%s\t%#010x\t%#010x\t%#010x\n",FactoryName,CpuFacName[1],CpuFacName[3],CpuFacName[2]);
    
    //brand_string
    for(i = 0x80000002;i < 0x80000005;i++)
    {
        get_cpuid(i,0,&CpuFacName[0],&CpuFacName[1],&CpuFacName[2],&CpuFacName[3]);

        *(unsigned int*)&FactoryName[0] = CpuFacName[0];

        *(unsigned int*)&FactoryName[4] = CpuFacName[1];

        *(unsigned int*)&FactoryName[8] = CpuFacName[2];

        *(unsigned int*)&FactoryName[12] = CpuFacName[3];

        FactoryName[16] = '\0';
        color_printk(YELLOW,BLACK,"%s",FactoryName);
    }
    color_printk(YELLOW,BLACK,"\n");

    //Version Informatin Type,Family,Model,and Stepping ID
    get_cpuid(1,0,&CpuFacName[0],&CpuFacName[1],&CpuFacName[2],&CpuFacName[3]);
    color_printk(YELLOW,BLACK,"Family Code:%#010x,Extended Family:%#010x,Model Number:%#010x,Extended Model:%#010x,Processor Type:%#010x,Stepping ID:%#010x\n",(CpuFacName[0] >> 8 & 0xf),(CpuFacName[0] >> 20 & 0xff),(CpuFacName[0] >> 4 & 0xf),(CpuFacName[0] >> 16 & 0xf),(CpuFacName[0] >> 12 & 0x3),(CpuFacName[0] & 0xf));

    //get Linear/Physical Address size
    get_cpuid(0x80000008,0,&CpuFacName[0],&CpuFacName[1],&CpuFacName[2],&CpuFacName[3]);
    color_printk(YELLOW,BLACK,"Physical Address size:%08d,Linear Address size:%08d\n",(CpuFacName[0] & 0xff),(CpuFacName[0] >> 8 & 0xff));

    //max cpuid operation code
    get_cpuid(0,0,&CpuFacName[0],&CpuFacName[1],&CpuFacName[2],&CpuFacName[3]);
    color_printk(WHITE,BLACK,"MAX Basic Operation Code :%#010x\t",CpuFacName[0]);

    get_cpuid(0x80000000,0,&CpuFacName[0],&CpuFacName[1],&CpuFacName[2],&CpuFacName[3]);
    color_printk(WHITE,BLACK,"MAX Extended Operation Code :%#010x\n",CpuFacName[0]);


}

功能號(hào) 0x00 獲取處理器的供應(yīng)商標(biāo)識(shí)

功能號(hào) 0x00 獲取處理器的供應(yīng)商標(biāo)識(shí)
  • get_cpuid(0,0,&CpuFacName[0],&CpuFacName[1],&CpuFacName[2],&CpuFacName[3]); 傳入的功能號(hào)0x00
  • *(unsigned int*)&FactoryName[0] = CpuFacName[1];
    其中 CpuFacName[1] = 0x756e6547 代表 "Genu"
  • *(unsigned int*)&FactoryName[0] 先取FactoryName[0]的地址腹鹉,然后就是將 0x756e6547 填入FactoryName[0] FactoryName[1] FactoryName[2] FactoryName[3]
  • color_printk(YELLOW,BLACK,"%s\t%#010x\t%#010x\t%#010x\n",FactoryName,CpuFacName[1],CpuFacName[3],CpuFacName[2]); 其中 %s0x756e6547 看做字符串 Genu輸出,%#010x直接輸出數(shù)值0x756e6547

功能號(hào)0x80002~0x80004 獲取處理器商標(biāo)信息

功能號(hào)0x80002~0x80004 獲取處理器商標(biāo)信息
  • for(i = 0x80000002;i < 0x80000005;i++) { }

init_cpu() 在何處被調(diào)用 敷硅?

通常情況下功咒,這些數(shù)據(jù)(處理器固件信息),應(yīng)該最先被操作系統(tǒng)捕獲绞蹦,隨后操作系統(tǒng)再根據(jù)處理器的固件信息來確定處理器支持的功能力奋,以便進(jìn)一步初始化處理器。
因此幽七,將init_cpu函數(shù)插入到系統(tǒng)異常處理功能的初始化函數(shù)( sys_vector_init();)之后會(huì)更妥當(dāng)一些

代碼清單8-6 第8章\程序\程序8-2\物理平臺(tái)\kernel\main.c

void Start_Kernel(void)
{
    ……
    sys_vector_init();

    init_cpu();
    ……
}

參考資料

[ATT匯編]程序舉例:xxx.S 編譯景殷、鏈接、運(yùn)行澡屡、調(diào)試 (CPUID命令 顯示處理器廠商信息)
http://www.reibang.com/p/91506500523a

[內(nèi)聯(lián)匯編]擴(kuò)展asm:格式猿挚、占位符、跳轉(zhuǎn)挪蹭、內(nèi)聯(lián)匯編宏函數(shù)
http://www.reibang.com/p/76fda24ee7f7

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末亭饵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子梁厉,更是在濱河造成了極大的恐慌辜羊,老刑警劉巖踏兜,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異八秃,居然都是意外死亡碱妆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門昔驱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疹尾,“玉大人,你說我怎么就攤上這事骤肛∧杀荆” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵腋颠,是天一觀的道長(zhǎng)繁成。 經(jīng)常有香客問我,道長(zhǎng)淑玫,這世上最難降的妖魔是什么巾腕? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮絮蒿,結(jié)果婚禮上尊搬,老公的妹妹穿的比我還像新娘。我一直安慰自己土涝,他們只是感情好佛寿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著回铛,像睡著了一般狗准。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茵肃,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音袭祟,去河邊找鬼验残。 笑死,一個(gè)胖子當(dāng)著我的面吹牛巾乳,可吹牛的內(nèi)容都是我干的您没。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼胆绊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼氨鹏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起压状,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤仆抵,失蹤者是張志新(化名)和其女友劉穎跟继,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镣丑,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舔糖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了莺匠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片金吗。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖趣竣,靈堂內(nèi)的尸體忽然破棺而出摇庙,到底是詐尸還是另有隱情,我是刑警寧澤遥缕,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布卫袒,位于F島的核電站,受9級(jí)特大地震影響通砍,放射性物質(zhì)發(fā)生泄漏玛臂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一封孙、第九天 我趴在偏房一處隱蔽的房頂上張望迹冤。 院中可真熱鬧,春花似錦虎忌、人聲如沸泡徙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽堪藐。三九已至,卻和暖如春挑围,著一層夾襖步出監(jiān)牢的瞬間礁竞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工杉辙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留模捂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓蜘矢,卻偏偏與公主長(zhǎng)得像狂男,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子品腹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容