色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

頁表創建源碼分析RISC-V Linux

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

頁表創建源碼分析

RISC-V Linux啟動,經歷了兩次頁表創建過程,第一次使用C函數setup_vm()創建臨時頁表,第二次使用C函數setup_vm_final()創建最終頁表。

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

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加載的其實物理地址
    //load_sz就是kernel的實際大小

    //page_offset就是kernel的起始物理地址對應的虛擬地址,va_pa_offset是他們的偏移量
 va_pa_offset = PAGE_OFFSET - load_pa;
    
    //計算得到kernel起始物理地址的物理頁,PFN_DOWN是將物理地址右移12位,因為sv39的物理地址的低12位是pa_offset,所以右移12位,得到pfn
 pfn_base = PFN_DOWN(load_pa);

 map_size = PMD_SIZE;//PMD_SIZE為2M,在當前,map_size只能為PGDIR_SIZE或PMD_SIZE。這時kernel默認不允許建立PTE。

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

    //allc_pte_early里面是BUG(),對于臨時頁表,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
 /* 設置 early PGD for fixmap */
 create_pgd_mapping(early_pg_dir, FIXADDR_START,
      (uintptr_t)fixmap_pgd_next, PGDIR_SIZE, PAGE_TABLE);


 /* 設置 fixmap PMD */
 create_pmd_mapping(fixmap_pmd, FIXADDR_START,
      (uintptr_t)fixmap_pte, PMD_SIZE, PAGE_TABLE);
 /* 設置 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);

 /*
  * 設置覆蓋整個內核的早期PGD,這將使我們能夠達到paging_init()。
  * 稍后在下面的 setup_vm_final() 中映射所有內存。
  */
 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創建早期的PMD */
 create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA,
      (uintptr_t)early_dtb_pmd, PGDIR_SIZE, PAGE_TABLE);
 /* 為 FDT 早期掃描創建兩個連續的 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()在最開始就進行了kernel入口地址的對齊檢查,要求入口地址2M對齊。假設內存起始地址為0x80000000,那么kernel只能放在0x80000000、0x80200000等2M對齊處。為什么會有這種對齊要求呢?

我猜測單純是為給opensbi預留了2M空間,因為kernel之前還有opensbi,而opensbi運行完之后,默認跳轉地址就是偏移2M,kernel只是為了跟opensbi對應,所以設置了2M對齊。

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

setup_vm_final()

在該函數中開始為整個物理內存做內存映射,通過swapper頁表來管理,并且清除掉匯編階段的頁表。

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

 /**
  * 此時MMU已經開啟,但是頁表還沒完全建立。
  */
 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);

 /* 為整個物理內存創建頁表 */
 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對齊或者kernel大小能被2M整除時,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頁表,這個是最終的頁表,匯編階段relocate開啟MMU的操作,跟下面這句是一樣的。 */
 csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE);
 local_flush_tlb_all();//刷新TLB

 ......
}

說明:

在setup_vm_final()函數中,通過swapper_pg_dir頁表來管理整個物理內存的訪問。并且清除匯編階段的頁表fixmap_pte和early_pg_dir。(本質上就是把該頁表項的內容清0,即賦值為0)

最終把swapper_pg_dir頁表的物理地址賦值給SATP寄存器。這樣CPU就可以通過該頁表訪問整個物理內存。

切換頁表通過如下實現:

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中的一個全局變量)

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11292

    瀏覽量

    209331
  • 代碼
    +關注

    關注

    30

    文章

    4779

    瀏覽量

    68525
  • RISC
    +關注

    關注

    6

    文章

    462

    瀏覽量

    83710
收藏 人收藏

    評論

    相關推薦

    自制RISC-V源碼與設計流程案例分析

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

    如何使用RISC-V創建自定義處理器

    采用RISC-V來替代其自定義體系結構。該體系結構吸引人的一個關鍵特征是,CPU開發人員可以在不犧牲為基本標準創建的工具和庫的適用性的情況下,使RISC-V功能適應其需求。適應的關鍵在于了解R
    的頭像 發表于 04-14 15:55 ?4141次閱讀
    如何使用<b class='flag-5'>RISC-V</b><b class='flag-5'>創建</b>自定義處理器

    RISC-V能否復制Linux 的成功?》

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

    基于risc-v架構的芯片與linux系統兼容性討論

    一直對基于RISC-V架構的芯片與Linux系統的兼容性比較感興趣,查了各種資料,眾說紛紜,在此整理一下學習內容,以備后用。這個復雜而重要的話題,涉及多個方面的考量。下面談談我的學習總結
    發表于 11-30 17:20

    科普RISC-V生態架構(認識RISC-V)

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

    分析RISC-V架構的不同之處

    0 RISC-V和其他開放架構有何不同如果僅從“免費”或“開放”這兩點來評判,RISC-V架構并不是第一個做到免費或開放的處理器架構。在開始之前,我們先通過論述幾個具有代表性的開放架構,來分析
    發表于 07-26 06:58

    RISC-V-Reader-Chinese-v2p1 RISC-V手冊(中文) RISC-V開源指令集的指南

    RISC-V 手冊 一本開源指令集的指南 本書是由 RISC-V 設計者 DAVID PATTERSON等親自寫的書。書寫的非常精彩,和Risc-V一樣非常簡潔明了,沒有廢話,書本身也不厚,114
    發表于 04-22 18:04

    【轉載】RISC-V 能打 50 年!risc-v 現在和未來的發展

    人性化的設定,大大降低了芯片的研究門檻,使 RISC-V 被譽為“半導體行業的 Linux”,廣受開發者歡迎。據分析機構 Semico Research 的《RISC-V 市場
    發表于 02-27 20:02

    我了解的RISC-V

    幾十條指令。 RISC-V的規范文檔僅有145,而“特權架構文檔”的篇幅也僅為91。 易于移植*nix 現代操作系統都做了特權級指令和用戶級指令的分離,特權指令只能操作系統調用,而用戶級指令才能
    發表于 03-19 10:52

    RISC-V的商業模式,國內外RISC-V的產業生態分析

    RISC-V將是智慧物聯網創新發展的新機遇,本文首先介紹了什么是指令集架構,其次介紹了RISC-V的歷史機遇、RISC-V的商業模式及中國CPU的未來展望,最后對國內外RISC-V的發
    的頭像 發表于 06-22 16:14 ?3542次閱讀
    <b class='flag-5'>RISC-V</b>的商業模式,國內外<b class='flag-5'>RISC-V</b>的產業生態<b class='flag-5'>分析</b>

    RISC-V的挑戰分析

    雖然RISC-V相關的開發和應用方面已經取得了長足進步,但前面還有一些障礙。普林斯頓大學的研究人員發現了RISC-V開源處理器內核的一些缺陷,他們認為這些缺陷關系重大。他們發現,在RISC-V處理器
    的頭像 發表于 02-25 09:41 ?2784次閱讀

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

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

    RISC-V設計支持工具,支持RISC-V技術的基礎

    RISC-V設計支持工具,支持RISC-V技術的基礎 ppt分享
    發表于 07-14 17:15 ?12次下載

    Arch Linux RISC-V 端口及相關作品簡介

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

    RISC-V Linux創建

    臨時分析 MMU開啟前,需要建立好kernel、dtb、trampoline等。以便MMU開啟后,并且在內存管理模塊運行之前,ker
    的頭像 發表于 10-08 11:14 ?575次閱讀
    主站蜘蛛池模板: 美女拉开腿让男生桶到爽| 午夜在线观看免费完整直播网| free高跟丝袜秘书hd| 四虎影视库永久免费| 美女被爆插| 国产又黄又硬又粗| 18禁裸乳无遮挡免费网站| 国产 亚洲 中文在线 字幕 | 精品国产三级a| 亚洲AV无码国产精品午夜久久| 欧美wwwvideos在线观看| 快播h网站| 99热在线精品免费全部my| 一本色道久久综合亚洲精品 | 国产精品毛片AV久久97| 99视频精品免视3| 欲香欲色天天天综合和网| 亚洲精品免费视频| 亚洲精品视频在线观看视频| 无限资源在线观看8| 双性h浪荡受bl| 午夜DY888国产精品影院| 无限资源网免费看| 亚洲第一色网站| 亚洲电影第1页| 亚洲视频在线观看地址| 欧美亚洲国产激情一区二区| 欧美四虎精品二区免费| 暖暖日本免费播放| 欧美亚洲色帝国| 前后灌满白浆护士| 日日色在线影院| 青青草原成人| 婷婷综合久久狠狠色| 我的漂亮朋友在线观看全集免费| 青青草原社区| 色女孩综合| 一本色道久久88综合日韩精品| 中文字幕一区二区三区在线不卡| writeas雷狮直播| 国产亚洲精品久久精品6|