在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

頁(yè)表創(chuàng)建源碼分析RISC-V Linux

麥辣雞腿堡 ? 來(lái)源:嵌入式Linux充電站 ? 作者:Vincent ? 2023-10-08 11:22 ? 次閱讀

頁(yè)表創(chuàng)建源碼分析

RISC-V Linux啟動(dòng),經(jīng)歷了兩次頁(yè)表創(chuàng)建過(guò)程,第一次使用C函數(shù)setup_vm()創(chuàng)建臨時(shí)頁(yè)表,第二次使用C函數(shù)setup_vm_final()創(chuàng)建最終頁(yè)表。

具體細(xì)節(jié)參考代碼中的注釋,下面的代碼省略了一些不重要的部分。

setup_vm()

asmlinkage void __init setup_vm(uintptr_t dtb_pa)
{
 uintptr_t va, pa, end_va;
 uintptr_t load_pa = (uintptr_t)(&_start);
 uintptr_t load_sz = (uintptr_t)(&_end) - load_pa;
 uintptr_t map_size;
 //load_pa就是kernel加載的其實(shí)物理地址
    //load_sz就是kernel的實(shí)際大小

    //page_offset就是kernel的起始物理地址對(duì)應(yīng)的虛擬地址,va_pa_offset是他們的偏移量
 va_pa_offset = PAGE_OFFSET - load_pa;
    
    //計(jì)算得到kernel起始物理地址的物理頁(yè),PFN_DOWN是將物理地址右移12位,因?yàn)閟v39的物理地址的低12位是pa_offset,所以右移12位,得到pfn
 pfn_base = PFN_DOWN(load_pa);

 map_size = PMD_SIZE;//PMD_SIZE為2M,在當(dāng)前,map_size只能為PGDIR_SIZE或PMD_SIZE。這時(shí)kernel默認(rèn)不允許建立PTE。

 //檢查PAGE_OFFSET是否1G對(duì)齊,以及kernel入口地址是否2M對(duì)齊
 BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0);
 BUG_ON((load_pa % map_size) != 0);

    //allc_pte_early里面是BUG(),對(duì)于臨時(shí)頁(yè)表,kernel不允許我們建立PTE
 pt_ops.alloc_pte = alloc_pte_early;
 pt_ops.get_pte_virt = get_pte_virt_early;
#ifndef __PAGETABLE_PMD_FOLDED
 pt_ops.alloc_pmd = alloc_pmd_early;
 pt_ops.get_pmd_virt = get_pmd_virt_early;
#endif
 /* 設(shè)置 early PGD for fixmap */
 create_pgd_mapping(early_pg_dir, FIXADDR_START,
      (uintptr_t)fixmap_pgd_next, PGDIR_SIZE, PAGE_TABLE);


 /* 設(shè)置 fixmap PMD */
 create_pmd_mapping(fixmap_pmd, FIXADDR_START,
      (uintptr_t)fixmap_pte, PMD_SIZE, PAGE_TABLE);
 /* 設(shè)置 trampoline PGD and PMD */
 create_pgd_mapping(trampoline_pg_dir, PAGE_OFFSET,
      (uintptr_t)trampoline_pmd, PGDIR_SIZE, PAGE_TABLE);
 create_pmd_mapping(trampoline_pmd, PAGE_OFFSET,
      load_pa, PMD_SIZE, PAGE_KERNEL_EXEC);

 /*
  * 設(shè)置覆蓋整個(gè)內(nèi)核的早期PGD,這將使我們能夠達(dá)到paging_init()。
  * 稍后在下面的 setup_vm_final() 中映射所有內(nèi)存。
  */
 end_va = PAGE_OFFSET + load_sz;
 for (va = PAGE_OFFSET; va < end_va; va += map_size)
  create_pgd_mapping(early_pg_dir, va,
       load_pa + (va - PAGE_OFFSET),
       map_size, PAGE_KERNEL_EXEC);

 /* 為dtb創(chuàng)建早期的PMD */
 create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
      (uintptr_t)early_dtb_pmd, PGDIR_SIZE, PAGE_TABLE);
 /* 為 FDT 早期掃描創(chuàng)建兩個(gè)連續(xù)的 PMD 映射 */
 pa = dtb_pa & ~(PMD_SIZE - 1);
 create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA,
      pa, PMD_SIZE, PAGE_KERNEL);
 create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE,
      pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
 dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1));
 ......

}

setup_vm()在最開(kāi)始就進(jìn)行了kernel入口地址的對(duì)齊檢查,要求入口地址2M對(duì)齊。假設(shè)內(nèi)存起始地址為0x80000000,那么kernel只能放在0x80000000、0x80200000等2M對(duì)齊處。為什么會(huì)有這種對(duì)齊要求呢?

我猜測(cè)單純是為給opensbi預(yù)留了2M空間,因?yàn)閗ernel之前還有opensbi,而opensbi運(yùn)行完之后,默認(rèn)跳轉(zhuǎn)地址就是偏移2M,kernel只是為了跟opensbi對(duì)應(yīng),所以設(shè)置了2M對(duì)齊。

那opensbi需要占用2M這么大?實(shí)際上只需要幾百KB,因此opensbi和kernel中間有一段內(nèi)存是空閑的,沒(méi)有人使用。這個(gè)問(wèn)題我們下篇再講。

setup_vm_final()

在該函數(shù)中開(kāi)始為整個(gè)物理內(nèi)存做內(nèi)存映射,通過(guò)swapper頁(yè)表來(lái)管理,并且清除掉匯編階段的頁(yè)表。

static void __init setup_vm_final(void)
{
 uintptr_t va, map_size;
 phys_addr_t pa, start, end;
 u64 i;

 /**
  * 此時(shí)MMU已經(jīng)開(kāi)啟,但是頁(yè)表還沒(méi)完全建立。
  */
 pt_ops.alloc_pte = alloc_pte_fixmap;
 pt_ops.get_pte_virt = get_pte_virt_fixmap;
#ifndef __PAGETABLE_PMD_FOLDED
 pt_ops.alloc_pmd = alloc_pmd_fixmap;
 pt_ops.get_pmd_virt = get_pmd_virt_fixmap;
#endif
 /* Setup swapper PGD for fixmap */
 create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
      __pa_symbol(fixmap_pgd_next),
      PGDIR_SIZE, PAGE_TABLE);

 /* 為整個(gè)物理內(nèi)存創(chuàng)建頁(yè)表 */
 for_each_mem_range(i, &start, &end) {
  if (start >= end)
   break;
  if (start <= __pa(PAGE_OFFSET) &&
      __pa(PAGE_OFFSET) < end)
   start = __pa(PAGE_OFFSET);

        //best_map_size是選擇合適的映射大小,kernel入口地址2M對(duì)齊或者kernel大小能被2M整除時(shí),map_size就是2M,否則就是4K。
  map_size = best_map_size(start, end - start);
  for (pa = start; pa < end; pa += map_size) {
   va = (uintptr_t)__va(pa);
   create_pgd_mapping(swapper_pg_dir, va, pa,
        map_size, PAGE_KERNEL_EXEC);
  }
 }

 /* 清除fixmap的PMD和PTE */
 clear_fixmap(FIX_PTE);
 clear_fixmap(FIX_PMD);

 /* 切換到swapper頁(yè)表,這個(gè)是最終的頁(yè)表,匯編階段relocate開(kāi)啟MMU的操作,跟下面這句是一樣的。 */
 csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE);
 local_flush_tlb_all();//刷新TLB

 ......
}

說(shuō)明:

在setup_vm_final()函數(shù)中,通過(guò)swapper_pg_dir頁(yè)表來(lái)管理整個(gè)物理內(nèi)存的訪問(wèn)。并且清除匯編階段的頁(yè)表fixmap_pte和early_pg_dir。(本質(zhì)上就是把該頁(yè)表項(xiàng)的內(nèi)容清0,即賦值為0)

最終把swapper_pg_dir頁(yè)表的物理地址賦值給SATP寄存器。這樣CPU就可以通過(guò)該頁(yè)表訪問(wèn)整個(gè)物理內(nèi)存。

切換頁(yè)表通過(guò)如下實(shí)現(xiàn):

csr_write(CSR_SATP,PFN_DOWN(_pa(swapper_pg_dir))|SATP_MODE);

在swapper_pg_dir管理的kernel space中,其虛擬地址與物理地址空間的偏移是固定的,為va_pa_offset(定義在arch/riscv/mm/init.c中的一個(gè)全局變量)

注意:swapper_pg_dir管理的是kernel space的頁(yè)表,即它把物理內(nèi)存映射到的虛擬地址空間是只能kernel訪問(wèn)的。user space不能訪問(wèn),用戶空間如果訪問(wèn),必須自行建立頁(yè)表,把物理地址映射到user space的虛擬地址空間。kernel線程共享這個(gè)swapper_pg_dir頁(yè)表。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11314

    瀏覽量

    209785
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4797

    瀏覽量

    68712
  • RISC
    +關(guān)注

    關(guān)注

    6

    文章

    462

    瀏覽量

    83764
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    自制RISC-V源碼與設(shè)計(jì)流程案例分析

    Overlay 簡(jiǎn)介 RISC-V-On-PYNQ Overlay實(shí)現(xiàn)了在PYNQ-Z2板上的RISC-V處理器及工具鏈集成,并提供了完整的RISC-V源碼與設(shè)計(jì)流程,得益于PYNQ軟
    的頭像 發(fā)表于 11-08 10:05 ?6614次閱讀
    自制<b class='flag-5'>RISC-V</b><b class='flag-5'>源碼</b>與設(shè)計(jì)流程案例<b class='flag-5'>分析</b>

    如何使用RISC-V創(chuàng)建自定義處理器

    采用RISC-V來(lái)替代其自定義體系結(jié)構(gòu)。該體系結(jié)構(gòu)吸引人的一個(gè)關(guān)鍵特征是,CPU開(kāi)發(fā)人員可以在不犧牲為基本標(biāo)準(zhǔn)創(chuàng)建的工具和庫(kù)的適用性的情況下,使RISC-V功能適應(yīng)其需求。適應(yīng)的關(guān)鍵在于了解R
    的頭像 發(fā)表于 04-14 15:55 ?4165次閱讀
    如何使用<b class='flag-5'>RISC-V</b><b class='flag-5'>創(chuàng)建</b>自定義處理器

    RISC-V能否復(fù)制Linux 的成功?》

    的產(chǎn)品,Linux成為開(kāi)源軟件發(fā)展的基石。 這種成功是否可以復(fù)制到開(kāi)源硬件上呢?RISC-V這樣的指令集架構(gòu)(ISA)是否也可以像Linux內(nèi)核作為開(kāi)源軟件的基礎(chǔ)一樣,成為開(kāi)源硬件發(fā)展的基石呢? 這個(gè)
    發(fā)表于 11-26 20:20

    基于risc-v架構(gòu)的芯片與linux系統(tǒng)兼容性討論

    一直對(duì)基于RISC-V架構(gòu)的芯片與Linux系統(tǒng)的兼容性比較感興趣,查了各種資料,眾說(shuō)紛紜,在此整理一下學(xué)習(xí)內(nèi)容,以備后用。這個(gè)復(fù)雜而重要的話題,涉及多個(gè)方面的考量。下面談?wù)勎业膶W(xué)習(xí)總結(jié)
    發(fā)表于 11-30 17:20

    科普RISC-V生態(tài)架構(gòu)(認(rèn)識(shí)RISC-V)

    RISC-V,逐步完成全線產(chǎn)品遷移到RISC-V定制架構(gòu);MicroSemi提供基于Risc-V+Linux+CNN加速器的AI解決方案;印度***則大力資助基于RISC-V的處理器項(xiàng)
    發(fā)表于 08-02 11:50

    分析RISC-V架構(gòu)的不同之處

    0 RISC-V和其他開(kāi)放架構(gòu)有何不同如果僅從“免費(fèi)”或“開(kāi)放”這兩點(diǎn)來(lái)評(píng)判,RISC-V架構(gòu)并不是第一個(gè)做到免費(fèi)或開(kāi)放的處理器架構(gòu)。在開(kāi)始之前,我們先通過(guò)論述幾個(gè)具有代表性的開(kāi)放架構(gòu),來(lái)分析
    發(fā)表于 07-26 06:58

    RISC-V-Reader-Chinese-v2p1 RISC-V手冊(cè)(中文) RISC-V開(kāi)源指令集的指南

    RISC-V 手冊(cè) 一本開(kāi)源指令集的指南 本書是由 RISC-V 設(shè)計(jì)者 DAVID PATTERSON等親自寫的書。書寫的非常精彩,和Risc-V一樣非常簡(jiǎn)潔明了,沒(méi)有廢話,書本身也不厚,114
    發(fā)表于 04-22 18:04

    【轉(zhuǎn)載】RISC-V 能打 50 年!risc-v 現(xiàn)在和未來(lái)的發(fā)展

    人性化的設(shè)定,大大降低了芯片的研究門檻,使 RISC-V 被譽(yù)為“半導(dǎo)體行業(yè)的 Linux”,廣受開(kāi)發(fā)者歡迎。據(jù)分析機(jī)構(gòu) Semico Research 的《RISC-V 市場(chǎng)
    發(fā)表于 02-27 20:02

    我了解的RISC-V

    幾十條指令。 RISC-V的規(guī)范文檔僅有145頁(yè),而“特權(quán)架構(gòu)文檔”的篇幅也僅為91頁(yè)。 易于移植*nix 現(xiàn)代操作系統(tǒng)都做了特權(quán)級(jí)指令和用戶級(jí)指令的分離,特權(quán)指令只能操作系統(tǒng)調(diào)用,而用戶級(jí)指令才能
    發(fā)表于 03-19 10:52

    RISC-V的商業(yè)模式,國(guó)內(nèi)外RISC-V的產(chǎn)業(yè)生態(tài)分析

    RISC-V將是智慧物聯(lián)網(wǎng)創(chuàng)新發(fā)展的新機(jī)遇,本文首先介紹了什么是指令集架構(gòu),其次介紹了RISC-V的歷史機(jī)遇、RISC-V的商業(yè)模式及中國(guó)CPU的未來(lái)展望,最后對(duì)國(guó)內(nèi)外RISC-V的發(fā)
    的頭像 發(fā)表于 06-22 16:14 ?3557次閱讀
    <b class='flag-5'>RISC-V</b>的商業(yè)模式,國(guó)內(nèi)外<b class='flag-5'>RISC-V</b>的產(chǎn)業(yè)生態(tài)<b class='flag-5'>分析</b>

    RISC-V的挑戰(zhàn)分析

    雖然RISC-V相關(guān)的開(kāi)發(fā)和應(yīng)用方面已經(jīng)取得了長(zhǎng)足進(jìn)步,但前面還有一些障礙。普林斯頓大學(xué)的研究人員發(fā)現(xiàn)了RISC-V開(kāi)源處理器內(nèi)核的一些缺陷,他們認(rèn)為這些缺陷關(guān)系重大。他們發(fā)現(xiàn),在RISC-V處理器
    的頭像 發(fā)表于 02-25 09:41 ?2805次閱讀

    RISC-VRISC-V AI的未來(lái)(特邀講座)

    主題演講:RISC-VRISC-V AI的未來(lái)(特邀講座)ppt分享
    發(fā)表于 07-14 17:15 ?16次下載

    RISC-V設(shè)計(jì)支持工具,支持RISC-V技術(shù)的基礎(chǔ)

    RISC-V設(shè)計(jì)支持工具,支持RISC-V技術(shù)的基礎(chǔ) ppt分享
    發(fā)表于 07-14 17:15 ?12次下載

    Arch Linux RISC-V 端口及相關(guān)作品簡(jiǎn)介

    Arch Linux RISC-V 端口及相關(guān)作品簡(jiǎn)介 演講ppt分享
    發(fā)表于 07-17 16:34 ?6次下載

    RISC-V Linux頁(yè)創(chuàng)建

    臨時(shí)頁(yè)分析 MMU開(kāi)啟前,需要建立好kernel、dtb、trampoline等頁(yè)。以便MMU開(kāi)啟后,并且在內(nèi)存管理模塊運(yùn)行之前,ker
    的頭像 發(fā)表于 10-08 11:14 ?601次閱讀
    主站蜘蛛池模板: 爱看精品福利视频观看| 国产免费色视频| 黄色片xxx| 天天操天天干天天| 成人国内精品久久久久影院| 欧美色视频日本| 四虎在线电影| 欧美性猛交xxxx乱大交高清| 色干干| 在线免费色视频| 国产va免费精品高清在线观看| 你懂得视频在线| 色狠狠狠色噜噜噜综合网| 最新国产厕所| 亚洲一区免费看| 好黄好硬好爽好刺激| 国产黄在线观看| 超级淫小黄文大全很污的那种 | 手机在线色| 婷婷午夜天| 五月婷婷丁香综合| 日本亚洲成人| 日韩一级特黄毛片在线看| 四虎影视最新地址| 女人色视频| 成年男人永久免费看片| 国产经典三级| 国产毛片久久久久久国产毛片| 91在线网址| 午夜神马福利影院| bt种子搜索在线| 在线观看免费xx高清视频| 人人干综合| mm131美女肉体艺术图片| 4444狠狠| 免费啪啪网| 68日本xxxxxxxxx xx| 亚洲二区在线观看| 性欧美欧美| 91夫妻视频| 欧美视频三区|