L'article précédent a analysé la création de table de pages pour le démarrage de RISC-V Linux. Il a été mentionné que l'adresse d'entrée RISC-V Linux doit être alignée sur 2M. Aujourd'hui, je vais parler de la façon de résoudre le problème d'alignement 2M, ou de la manière de le faire. optimiser une partie de la mémoire.
Remarque : cet article est basé sur le noyau Linux5.10.111
Lorsque chaque puce quitte l'usine, son bootrom a été solidifié à l'intérieur de la puce. Supposons que l'adresse de. le bootrom est 0x0, c'est-à-dire ce qui précède. Après la mise sous tension, le programme commencera à s'exécuter à partir de l'adresse 0x0.
Avant de démarrer RISC-V Linux, vous devez d'abord exécuter opensbi, donc opensbi doit être placé à l'adresse 0x0
处,这样芯片上电后,就会从0x0
地址处执行opensbi。在opensbi运行完后,会跳转到opensbi运行地址偏移2M的位置去执行下一级boot(这里下一级boot是kernel),即跳转到0x200000
地址处运行kernel,因此应该把kernel放到内存的0x200000
.
Le schéma de répartition de la mémoire est le suivant :
Pour le noyau, il chargera l'adresse de son propre noyau au démarrage (c'est-à-dire 0x200000
) commence à établir le mappage de la table des pages. Ce n'est que lorsque le mappage de la table des pages est établi pour la mémoire physique que ces mémoires sont accessibles ultérieurement. Le noyau charge la mémoire 2M devant l'adresse (c'est-à-dire 0x0 - 0x200000
) sera ignoré par le noyau et la table des pages ne sera pas établie pour ces 2 Mo de mémoire, c'est-à-dire que le noyau ne pourra pas accéder à ces 2 Mo de mémoire. 0x200000
)开始建立页表映射,只有对物理内存建立了页表映射,后面才能访问这些内存。而kernel加载地址前面的2M内存(即0x0 - 0x200000
)将被kernel忽略,不会对这2M内存建立页表,即kernel无法访问这2M内存。
在QEMU上RISC-V Linux的启动信息:
但opensbi实际不需要使用2M这么大的范围,默认是512KB
,opensbi的pmp会保护这512KB
内存,不让其他程序访问。
因此在Kernel和opensbi之间会存在1.5M
512 Ko
, le pmp d'opensbi protégera ceci512 Ko
mémoire, non accessible à d'autres programmes.
1,5 M
espace mémoire et cette partie de l'espace mémoire n'est pas utilisée par le programme, ce qui entraînera un gaspillage de mémoire. Alors comment laisser le noyau utiliser la partie précédente de la mémoire ?
Plan d'optimisation
Il existe deux plans pour optimiser cette mémoire de 2 Mo : 🎜🎜🎜Option 1🎜 : Mettez opensbi à la fin de la mémoire, et l'adresse d'entrée du noyau conserve toujours l'alignement de 2 M. 🎜🎜🎜Option 2🎜 : Opensbi est toujours placé au début de la mémoire. En modifiant le code source du noyau et en levant la restriction d'alignement 2M, l'adresse du noyau peut être avancée. 🎜
Nous mettons opensbi à la fin de la mémoire, et l'adresse d'entrée du noyau maintient toujours l'alignement 2M.
C'est-à-dire que le noyau est placé à l'avant de la mémoire, et opensbi est placé à l'arrière :
Par exemple, le noyau est placé à l'adresse 0x0
地址处,opensbi放到内存的0x10000000
地址处。这样kernel前面就不会有预留内存,只不过这样需要修改bootrom的地址,将地址从0x0
修改为0x0x10000000
。这种方案只适合芯片还没出厂前,因为用户无法修改bootrom的地址,芯片出厂后,bootrom地址是固定的,假设bootrom地址为0x0
,那么芯片上电后,就会从0x0
开始运行程序,所以opensbi必须放到0x0
de la mémoire, donc le noyau ne peut être décalé de 2M.
Nous pouvons également modifier le code source du noyau de RISC-V Linux pour lever la restriction d'alignement 2M. Il nous suffit de setup_vm ()
, changez la table de pages de deuxième niveau d'origine en une table de pages de troisième niveau, de sorte que l'adresse d'entrée du noyau n'ait besoin que d'être alignée sur 4K, afin que le noyau puisse être avancé, utilisant ainsi la mémoire avant. setup_vm()
函数中,将原来的二级页表改为三级页表,这样kernel入口地址只需要4K对齐,因此就能将kernel往前挪,从而利用前面的内存。
路径:arch/riscv/mm/init.c
Modifier le code
Commentez la vérification d'alignement 2M d'origine :
Modifiez le premier mappage de la table de pages 2M du noyau de la table des pages de deuxième niveau à la table des pages de troisième niveau :
//新增一个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); }
Le mappage de la table des pages de l'ensemble du noyau est modifié de la table des pages de deuxième niveau à la table des pages de troisième niveau : Supposons que la taille du noyau est de 4M+
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!