실용적인 전투 | RISC-V Linux 항목 주소 2M 예약 메모리 최적화
이전 기사에서는 RISC-V Linux 시작을 위한 페이지 테이블 생성을 분석했습니다. RISC-V Linux 항목 주소는 2M 정렬되어야 한다고 언급되었습니다. 오늘은 2M 정렬 문제를 해결하는 방법에 대해 이야기하겠습니다. 메모리의 일부를 최적화합니다.
참고: 이 기사는 linux5.10.111 커널을 기반으로 합니다.
메모리 사용량 분석
각 칩이 공장에서 출고될 때 해당 부트롬은 칩 내부에 굳어져 있다고 가정합니다. bootrom은 0x0, 즉 위와 같습니다. 전원을 켜면 프로그램은 주소 0x0에서 실행됩니다.
RISC-V Linux를 시작하기 전에 먼저 opensbi를 실행해야 하므로 opensbi는 0x0
处,这样芯片上电后,就会从0x0
地址处执行opensbi。在opensbi运行完后,会跳转到opensbi运行地址偏移2M的位置去执行下一级boot(这里下一级boot是kernel),即跳转到0x200000
地址处运行kernel,因此应该把kernel放到内存的0x200000
주소에 배치되어야 합니다.
메모리 분포 다이어그램은 다음과 같습니다.

커널의 경우 시작 시 자체 커널에서 주소를 로드합니다(예: 0x200000
) 페이지 테이블 매핑을 설정하기 시작합니다. 물리적 메모리에 대해 페이지 테이블 매핑이 설정되어야 나중에 해당 메모리에 액세스할 수 있습니다. 커널은 주소 앞에 2M 메모리를 로드합니다(예: 0x0 - 0x200000
)은 커널에 의해 무시되며 이 2M 메모리에 대한 페이지 테이블이 설정되지 않습니다. 즉, 커널은 이 2M 메모리에 액세스할 수 없습니다. 0x200000
)开始建立页表映射,只有对物理内存建立了页表映射,后面才能访问这些内存。而kernel加载地址前面的2M内存(即0x0 - 0x200000
)将被kernel忽略,不会对这2M内存建立页表,即kernel无法访问这2M内存。
在QEMU上RISC-V Linux的启动信息:

但opensbi实际不需要使用2M这么大的范围,默认是512KB
,opensbi的pmp会保护这512KB
内存,不让其他程序访问。

因此在Kernel和opensbi之间会存在1.5M
하지만 opensbi는 실제로 2M만큼 큰 범위를 사용할 필요가 없습니다. 기본값은 512KB
, opensbi의 pmp는 이것을 보호합니다512KB
메모리, 다른 프로그램에서 액세스할 수 없습니다.
그래서 1.5M
메모리 간격 및 메모리 공백의 이 부분은 프로그램에서 사용되지 않으므로 메모리 낭비가 발생합니다. 그러면 커널이 메모리의 이전 부분을 사용하도록 하는 방법은 무엇입니까?
최적화 계획
이 2M 메모리를 최적화하기 위한 두 가지 계획이 있습니다: 🎜🎜🎜옵션 1🎜: opensbi를 메모리 끝에 넣고 커널 항목 주소는 여전히 2M 정렬을 유지합니다. 🎜🎜🎜옵션 2🎜: Opensbi는 여전히 메모리 시작 부분에 배치됩니다. 커널 소스 코드를 수정하고 2M 정렬 제한을 해제하면 커널 주소를 앞으로 이동할 수 있습니다. 🎜
Option 1
opensbi를 메모리 끝에 두었고 커널 항목 주소는 여전히 2M 정렬을 유지합니다.
즉, 커널은 메모리 앞쪽에 배치되고, opensbi는 뒤쪽에 배치됩니다.

예를 들어 커널은 메모리의 0x0
地址处,opensbi放到内存的0x10000000
地址处。这样kernel前面就不会有预留内存,只不过这样需要修改bootrom的地址,将地址从0x0
修改为0x0x10000000
。这种方案只适合芯片还没出厂前,因为用户无法修改bootrom的地址,芯片出厂后,bootrom地址是固定的,假设bootrom地址为0x0
,那么芯片上电后,就会从0x0
开始运行程序,所以opensbi必须放到0x0
주소에 배치되므로 커널은 2M만큼 오프셋됩니다.
옵션 2
또한 RISC-V Linux의 커널 소스 코드를 수정하여 2M 정렬 제한을 해제할 수도 있습니다. setup_vm ()
함수를 사용하여 원래 두 번째 수준 페이지 테이블을 세 번째 수준 페이지 테이블로 변경하여 커널 항목 주소를 4K로만 정렬하면 커널이 앞으로 이동하여 전면 메모리를 사용합니다. setup_vm()
函数中,将原来的二级页表改为三级页表,这样kernel入口地址只需要4K对齐,因此就能将kernel往前挪,从而利用前面的内存。
修改代码
路径:arch/riscv/mm/init.c
코드 수정

아치 / riscv/mm/init.c
원래 2M 정렬 검사에 주석을 추가하세요.

두 번째 수준 페이지 테이블에서 세 번째 수준 페이지 테이블로 커널의 첫 번째 2M 페이지 테이블 매핑을 변경합니다.
//新增一个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); }
전체 커널의 페이지 테이블 매핑이 2단계 페이지 테이블에서 3단계 페이지 테이블로 변경됩니다.


//定义三个PTE pte_t load_sz_pte[PTRS_PER_PTE] __page_aligned_bss; pte_t load_sz_pte1[PTRS_PER_PTE] __page_aligned_bss; pte_t load_sz_pte2[PTRS_PER_PTE] __page_aligned_bss; //=======0-2M====== create_pgd_mapping(early_pg_dir,PAGE_OFFSET, (uintptr_t)early_pmd,PGDIR_SIZE,PAGE_TABLE); create_pmd_mapping(early_pmd,PAGE_OFFSET, (uintptr_t)load_sz_pte,PMD_SIZE,PAGE_TABLE); end_va = PAGE_OFFSET + PMD_SIZE; for (va = PAGE_OFFSET; va < end_va; va += PAGE_SIZE) { create_pte_mapping(load_sz_pte,PAGE_OFFSET, load_pa + (va - PAGE_OFFSET), PAGE_SIZE,PAGE_KERNEL_EXEC); } //=======2-4M========== create_pgd_mapping(early_pg_dir,PAGE_OFFSET + PMD_SIZE, (uintptr_t)early_pmd,PGDIR_SIZE,PAGE_TABLE); create_pmd_mapping(early_pmd,PAGE_OFFSET, (uintptr_t)load_sz_pte1,PMD_SIZE,PAGE_TABLE); end_va = PAGE_OFFSET + (PMD_SIZE * 2); for (va = PAGE_OFFSET + PMD_SIZE; va < end_va; va += PAGE_SIZE) { create_pte_mapping(load_sz_pte1,va, load_pa + (va - PAGE_OFFSET), PAGE_SIZE,PAGE_KERNEL_EXEC); } //=======4-6M========== create_pgd_mapping(early_pg_dir,PAGE_OFFSET + (PMD_SIZE*2), (uintptr_t)early_pmd,PGDIR_SIZE,PAGE_TABLE); create_pmd_mapping(early_pmd,PAGE_OFFSET, (uintptr_t)load_sz_pte2,PMD_SIZE,PAGE_TABLE); end_va = PAGE_OFFSET + (PMD_SIZE * 3); for (va = PAGE_OFFSET + (PMD_SIZE*2); va < end_va; va += PAGE_SIZE) { create_pte_mapping(load_sz_pte2,va, load_pa + (va - PAGE_OFFSET), PAGE_SIZE,PAGE_KERNEL_EXEC); }

Summary
RISC-V Linux 항목 주소 2M 정렬 작업은 아직 설명되지 않았지만 opensbi를 위해 2M을 예약해야 하므로 커널은 보조 페이지 테이블만 설정하므로 항목 주소는 2M로 정렬되어야 합니다. 아직까지 메모리의 이 부분에 대한 최적화 솔루션을 제시한 사람은 없습니다. 이 기사의 최적화 솔루션이 일부 사람들에게 도움이 되고 모든 사람에게 영감을 줄 수 있기를 바랍니다.
위 내용은 실용적인 전투 | RISC-V Linux 항목 주소 2M 예약 메모리 최적화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











운영 체제의 핵심 부분인 Linux 커널은 하드웨어 자원 관리 및 시스템 호출 제공과 같은 중요한 기능을 담당합니다. 이 기사에서는 프로세스 관리, 파일 시스템, 네트워크 통신, 장치 드라이버 및 메모리 관리를 포함하여 Linux 커널의 다섯 가지 주요 부분을 살펴보고 자세한 소개와 코드 예제를 제공합니다. 1. 프로세스 관리 프로세스 생성 Linux 커널에서 프로세스 생성은 fork() 시스템 호출을 통해 구현됩니다. 다음은 간단한 예제 코드입니다: #include

내용이 길고 기술적인 내용이 많기 때문에 클릭해서 따라가시면 길을 잃을 염려가 없습니다. 서문: Linux 커널 이해하기 컴퓨터 시스템은 하드웨어와 소프트웨어의 공생체이며 상호 의존적이며 분리될 수 없습니다. 컴퓨터 하드웨어 Linux 커널 이식 단계에는 컴퓨터 실린더를 구성하는 주변 장치, 프로세서, 메모리, 하드 드라이브 및 기타 전자 장치가 포함됩니다. 그리고 이를 작동하고 제어하는 소프트웨어가 없으면 자체적으로 작동할 수 없습니다. 이러한 제어 작업을 완료하는 소프트웨어를 Linux 용어로 "커널" 또는 "코어"라고 합니다. Linux 커널의 주요 모듈(또는 구성 요소)은 스토리지 관리, CPU 및 프로세스 관리, 파일 시스템, 장치 관리 및 드라이버, 네트워크 통신 Linux 포럼, 시스템 등의 부분으로 나뉩니다.

이전 기사에서는 RISC-V Linux 시작을 위한 페이지 테이블 생성을 분석했습니다. RISC-V Linux 항목 주소는 2M 정렬되어야 한다고 언급되었습니다. 오늘은 2M 정렬 문제를 해결하는 방법이나 일부를 최적화하는 방법에 대해 설명하겠습니다. 기억.

안녕하세요, 독자 여러분! 여기서 저는 Linux 커널 TCP 프로토콜 스택의 개발 및 최적화 분야에서 전문적인 기술을 바탕으로 수석 네트워크 엔지니어로서 축적한 귀중한 경험과 기술을 여러분과 공유하게 된 것을 영광으로 생각합니다. 이 글을 통해 우리는 서로 배우고 토론할 수 있으며, 이 분야에 큰 관심을 가지고 있거나 관련 작업을 하고 있는 여러분에게 실용적이고 유용한 참고 자료를 제공할 수 있다고 믿습니다. 1. TCP 연결 설정 TCP 연결 설정은 TCP 프로토콜 스택의 핵심 트랜잭션이지만 많은 연결 문제에 직면하는 것은 드문 일이 아닙니다. 신중하게 고려하고 세부적으로 디버깅한 후 SYN 플러딩 공격 방지(시스템 매개변수 조정) 및 네트워크 정체 처리(즉, TCPFastOp 사용)를 포함하여 몇 가지 일반적이고 실제적인 문제와 해결 방법을 발견했습니다.

이것은 Linux 커널 소스 코드 배포를 심층적으로 탐구하는 1500 단어 분량의 기사입니다. 제한된 공간으로 인해 Linux 커널 소스 코드의 조직 구조에 중점을 두고 독자의 이해를 돕기 위해 몇 가지 구체적인 코드 예제를 제공합니다. Linux 커널은 소스 코드가 GitHub에서 호스팅되는 오픈 소스 운영 체제 커널입니다. 전체 Linux 커널 소스 코드 배포판은 매우 방대하며 여러 하위 시스템 및 모듈과 관련된 수십만 줄의 코드를 포함합니다. Linux 커널 소스 코드를 더 깊이 이해하려면

Linux 커널이 컴퓨터 운영 체제에서 중요한 역할을 한다는 관점을 논의합니다. Linux 커널 설계 및 실제 응용 프로그램에 대한 심층적인 분석을 통해 이 분야에서 Linux 커널의 탁월한 위치와 영향력을 드러냅니다. 1. 최적화된 메모리 관리 가상 메모리 관리 기술을 사용하여 Linux 커널은 메모리 할당 및 재활용을 효율적으로 완료할 수 있습니다. 교체 페이지 알고리즘의 도움으로 Linux 커널은 물리적 메모리와 가상 메모리 간의 매핑 관계를 정확하게 처리하도록 설계 및 구현되었습니다. 애플리케이션의 특정 요구 사항에 따라 유연하게 조정할 수 있으므로 전체 시스템 성능이 향상됩니다. 2. 강력한 프로세스 관리 커널은 뛰어난 멀티 태스킹 기술을 사용하여 단일 시스템에서 여러 프로세스가 조화롭게 공존할 수 있도록 합니다. 신중하게 구성됨

Android 시스템과 Linux 커널은 밀접하게 관련된 두 개체이며, 둘 사이의 관계는 밀접하고 복잡합니다. Android 시스템에서 Linux 커널은 Android 시스템에 대한 기본 하드웨어 드라이버 및 시스템 호출 지원을 제공하는 중요한 역할을 합니다. 이 기사에서는 Android 시스템과 Linux 커널 간의 관계, 상호 작용 및 작동 방식을 살펴보고 몇 가지 구체적인 코드 예제를 제공합니다. 안드로이드(Android)는 리눅스 커널을 기반으로 개발된 모바일 운영체제로 스마트폰, 태블릿 등 모바일 기기에 주로 사용된다. 엘

Linux 커널은 운영 체제의 핵심이며 CPU, I/O 장치, 물리적 메모리 및 파일 시스템과 같은 시스템 리소스에 대한 액세스를 제어합니다. 부팅 과정과 시스템이 실행되는 동안 커널은 커널 링 버퍼에 다양한 메시지를 씁니다. 이러한 메시지에는 시스템 작동에 대한 다양한 정보가 포함됩니다.
