Artikel sebelumnya menganalisis penciptaan jadual halaman untuk permulaan RISC-V Linux Disebutkan bahawa alamat kemasukan RISC-V Linux mesti sejajar 2M Hari ini saya akan bercakap tentang cara menyelesaikan masalah penjajaran 2M, atau bagaimana mengoptimumkan sebahagian daripada ingatan.
Nota: Artikel ini berdasarkan kernel linux5.10.111
Apabila setiap cip keluar dari kilang. Dengan anggapan cip itu telah kukuh di dalam kilang bootrom adalah 0x0, iaitu, di atas Selepas dihidupkan, program akan mula berjalan dari alamat 0x0.
Sebelum memulakan RISC-V Linux, anda perlu menjalankan opensbi terlebih dahulu, jadi opensbi perlu diletakkan di alamat 0x0
处,这样芯片上电后,就会从0x0
地址处执行opensbi。在opensbi运行完后,会跳转到opensbi运行地址偏移2M的位置去执行下一级boot(这里下一级boot是kernel),即跳转到0x200000
地址处运行kernel,因此应该把kernel放到内存的0x200000
.
Rajah agihan ingatan adalah seperti berikut:
Untuk kernel, ia akan memuatkan alamat dari kernelnya sendiri apabila bermula (iaitu 0x200000
) mula mewujudkan pemetaan jadual halaman. Hanya apabila pemetaan jadual halaman ditubuhkan untuk memori fizikal, kenangan ini boleh diakses kemudian. Kernel memuatkan memori 2M di hadapan alamat (iaitu 0x0 - 0x200000
) akan diabaikan oleh kernel, dan jadual halaman tidak akan ditubuhkan untuk memori 2M ini, iaitu, kernel tidak boleh mengakses memori 2M ini. 0x200000
)开始建立页表映射,只有对物理内存建立了页表映射,后面才能访问这些内存。而kernel加载地址前面的2M内存(即0x0 - 0x200000
)将被kernel忽略,不会对这2M内存建立页表,即kernel无法访问这2M内存。
在QEMU上RISC-V Linux的启动信息:
但opensbi实际不需要使用2M这么大的范围,默认是512KB
,opensbi的pmp会保护这512KB
内存,不让其他程序访问。
因此在Kernel和opensbi之间会存在1.5M
Kami meletakkan opensbi di hujung memori, dan alamat kemasukan kernel masih mengekalkan penjajaran 2M.
Iaitu, kernel diletakkan di hadapan memori, dan opensbi diletakkan di belakang:
Sebagai contoh, kernel diletakkan di alamat 0x0
地址处,opensbi放到内存的0x10000000
地址处。这样kernel前面就不会有预留内存,只不过这样需要修改bootrom的地址,将地址从0x0
修改为0x0x10000000
。这种方案只适合芯片还没出厂前,因为用户无法修改bootrom的地址,芯片出厂后,bootrom地址是固定的,假设bootrom地址为0x0
,那么芯片上电后,就会从0x0
开始运行程序,所以opensbi必须放到0x0
memori, jadi kernel hanya boleh diimbangi oleh 2M.
Kami juga boleh mengubah suai kod sumber kernel RISC-V Linux untuk menarik balik sekatan penjajaran 2M. Kita hanya perlu setup_vm ()
fungsi, tukar jadual halaman peringkat kedua asal kepada jadual halaman peringkat ketiga, supaya alamat kemasukan kernel hanya perlu diselaraskan pada 4K, supaya kernel boleh bergerak ke hadapan, dengan itu menggunakan ingatan hadapan. setup_vm()
函数中,将原来的二级页表改为三级页表,这样kernel入口地址只需要4K对齐,因此就能将kernel往前挪,从而利用前面的内存。
路径:arch/riscv/mm/init.c
Ubah suai kod
Ulas semakan penjajaran 2M asal:
Tukar pemetaan jadual halaman 2M pertama bagi kernel daripada jadual halaman peringkat kedua kepada jadual halaman peringkat ketiga :
//新增一个PTE pte_t trampoline_pte[PTRS_PER_PTE] __page_aligned_bss; create_pgd_mapping(trampoline_pg_dir,PAGE_OFFSET, (uintptr_t)trampoline_pmd,PGDIR_SIZE,PAGE_TABLE); create_pmd_mapping(trampoline_pmd,PAGE_OFFSET, (uintptr_t)trampoline_pte,PMD_SIZE,PAGE_TABLE); end_va = PAGE_OFFSET + PMD_SIZE; for (va = PAGE_OFFSET; va < end_va; va += PAGE_SIZE) { create_pte_mapping(trampoline_pte,PAGE_OFFSET, load_pa + (va - PAGE_OFFSET), PAGE_SIZE,PAGE_KERNEL_EXEC); }
Pemetaan jadual halaman keseluruhan kernel ditukar daripada jadual halaman peringkat kedua kepada jadual halaman peringkat ketiga: Andaikan saiz kernel ialah 4M+
Atas ialah kandungan terperinci Pertempuran praktikal |. RISC-V Linux alamat kemasukan 2M terpelihara pengoptimuman. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!