Part 1
요약·해설
Physical·virtual address 분리, PAE region 정렬, gen_mmu.py --map 형식과 page 예약을 다룹니다.
identity map · vm_enter · unmap
PAE · page directory · --map
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
CD486F40CED97A95D4F5327D3AD1FDC82A2CD4CF50F10C3E074923ADA73B9E6C
.. _x86_developer_guide:
x86 Developer Guide
###################
Overview
********
This page contains information on certain aspects when developing for
x86-based platforms.
Virtual Memory
**************
During very early boot, page tables are loaded so technically the kernel
is executing in virtual address space. By default, physical and virtual
memory are identity mapped and thus giving the appearance of execution
taking place in physical address space. The physical address space is
marked by kconfig :kconfig:option:`CONFIG_SRAM_BASE_ADDRESS` and
:kconfig:option:`CONFIG_SRAM_SIZE` while the virtual address space is marked by
:kconfig:option:`CONFIG_KERNEL_VM_BASE` and :kconfig:option:`CONFIG_KERNEL_VM_SIZE`.
Note that :kconfig:option:`CONFIG_SRAM_OFFSET` controls where the Zephyr kernel
is being placed in the memory, and its counterpart
:kconfig:option:`CONFIG_KERNEL_VM_OFFSET`.
Separate Virtual Address Space from Physical Address Space
==========================================================
On 32-bit x86, it is possible to have separate physical and virtual
address space. Code and data are linked in virtual address space,
but are still loaded in physical memory. However, during boot, code
and data must be available and also addressable in physical address
space before ``vm_enter`` inside :file:`arch/x86/core/ia32/crt0.S`.
After ``vm_enter``, code execution is done via virtual addresses
and data can be referred via their virtual addresses. This is
possible as the page table generation script
(:file:`arch/x86/gen_mmu.py`) identity maps the physical addresses
at the page directory level, in addition to mapping virtual addresses
to the physical memory. Later in the boot process,
the entries for identity mapping at the page directory level are
cleared in :c:func:`z_x86_mmu_init()`, effectively removing
the identity mapping of physical memory. This unmapping must be done
for userspace isolation or else they would be able to access
restricted memory via physical addresses. Since the identity mapping
is done at the page directory level, there is no need to allocate
additional space for the page table. However, additional space may
still be required for additional page directory table.
There are restrictions on where virtual address space can be:
- Physical and virtual address spaces must be disjoint. This is
required as the entries in page directory table will be cleared.
If they are not disjoint, it would clear the entries needed for
virtual addresses.
- If :kconfig:option:`CONFIG_X86_PAE` is enabled (``=y``), each address space
must reside in their own 1GB region, due to each entry of PDP
(Page Directory Pointer) covers 1GB of memory. For example:
- Assuming ``CONFIG_SRAM_OFFSET`` and ``CONFIG_KERNEL_VM_OFFSET``
are both ``0x0``.
- ``CONFIG_SRAM_BASE_ADDRESS == 0x00000000`` and
``CONFIG_KERNEL_VM_BASE = 0x40000000`` is valid, while
- ``CONFIG_SRAM_BASE_ADDRESS == 0x00000000`` and
``CONFIG_KERNEL_VM_BASE = 0x20000000`` is not.
- If :kconfig:option:`CONFIG_X86_PAE` is disabled (``=n``), each address space
must reside in their own 4MB region, due to each entry of PD
(Page Directory) covers 4MB of memory.
- Both ``CONFIG_SRAM_BASE_ADDRESS`` and ``CONFIG_KERNEL_VM_BASE``
must also align with the starting addresses of targeted regions.
Specifying Additional Memory Mappings at Build Time
***************************************************
The page table generation script (:file:`arch/x86/gen_mmu.py`) generates
the necessary multi-level page tables for code execution and data access
using the kernel image produced by the first linker pass. Additional
command line arguments can be passed to the script to generate additional
memory mappings. This is useful for static mappings and/or device MMIO
access during very early boot. To pass extra command line arguments to
the script, populate a CMake list named ``X86_EXTRA_GEN_MMU_ARGUMENTS``
in the board configuration file. Here is an example:
.. code-block:: cmake
set(X86_EXTRA_GEN_MMU_ARGUMENTS
--map 0xA0000000,0x2000
--map 0x80000000,0x400000,LWUX,0xB0000000)
The argument ``--map`` takes the following value:
``<physical address>,<size>[,<flags:LUWX>[,<virtual address>]]``, where:
- ``<physical address>`` is the physical address of the mapping. (Required)
- ``<size>`` is the size of the region to be mapped. (Required)
- ``<flags>`` is the flag associated with the mapping: (Optional)
- ``L``: Large page at the page directory level.
- ``U``: Allow userspace access.
- ``W``: Read/write.
- ``X``: Allow execution.
- ``D``: Cache disabled.
- Default is small page (4KB), supervisor only, read only, and
execution disabled.
- ``<virtual address`` is the virtual address of the mapping. (Optional)
Note that specifying additional memory mappings requires larger storage
space for the pre-allocated page tables (both kernel and per-domain
tables). :kconfig:option:`CONFIG_X86_EXTRA_PAGE_TABLE_PAGES` is needed to
specify how many more memory pages to be reserved for the page tables.
If the needed space is not exactly the same as required space,
the ``gen_mmu.py`` script will print out a message indicating what
needs to be the value for the kconfig.
Part 3
한국어 전문 번역
개요
이 페이지는 x86 기반 platform용 Zephyr를 개발할 때 필요한 일부 핵심 사항을 설명합니다.
Virtual memory
Boot 초기부터 page table이 load되므로 기술적으로 kernel은 virtual address space에서 실행됩니다. 기본 설정은 physical memory와 virtual memory를 identity mapping하여 physical address space에서 실행되는 것처럼 보입니다. Physical address space는 CONFIG_SRAM_BASE_ADDRESS와 CONFIG_SRAM_SIZE, virtual address space는 CONFIG_KERNEL_VM_BASE와 CONFIG_KERNEL_VM_SIZE가 정합니다. Kernel의 memory 내 배치는 CONFIG_SRAM_OFFSET과 대응하는 CONFIG_KERNEL_VM_OFFSET이 제어합니다.
Physical address space와 분리된 virtual address space
32-bit x86에서는 physical·virtual address space를 분리할 수 있습니다. Code와 data는 virtual address space 기준으로 link되지만 physical memory에 load됩니다. 그러나 boot 중 arch/x86/core/ia32/crt0.S의 vm_enter 전까지는 code와 data가 physical address space에서도 접근 가능해야 합니다.
arch/x86/gen_mmu.py page-table 생성 script가 virtual address를 physical memory에 mapping하는 것과 별도로 page-directory level에서 physical address를 identity mapping하므로 이것이 가능합니다. Boot 후반의 z_x86_mmu_init()가 page-directory level의 identity mapping entry를 지워 physical memory identity mapping을 제거합니다.
이 unmapping을 하지 않으면 userspace가 physical address를 통해 제한 memory에 접근할 수 있으므로 격리를 위해 반드시 필요합니다. Identity mapping은 page-directory level에서 하므로 page table 공간을 추가로 할당할 필요는 없지만, 추가 page-directory table 공간은 필요할 수 있습니다.
Virtual address space 위치에는 다음 제약이 있습니다.
- Physical·virtual address space는 서로 겹치지 않아야 합니다. Page-directory entry를 지울 때 virtual address에 필요한 entry까지 지워지는 것을 막기 위한 조건입니다.
CONFIG_X86_PAE=y이면 PDP(Page Directory Pointer) entry 하나가 1GB를 덮으므로 두 address space가 서로 다른 1GB region에 있어야 합니다.CONFIG_X86_PAE=n이면 PD(Page Directory) entry 하나가 4MB를 덮으므로 서로 다른 4MB region에 있어야 합니다.CONFIG_SRAM_BASE_ADDRESS와CONFIG_KERNEL_VM_BASE는 대상 region의 시작 address에 맞춰 정렬해야 합니다.
CONFIG_SRAM_OFFSET과 CONFIG_KERNEL_VM_OFFSET이 모두 0x0인 PAE 예에서 SRAM base 0x00000000과 kernel VM base 0x40000000 조합은 유효하지만, kernel VM base가 0x20000000이면 같은 1GB region이므로 유효하지 않습니다.
Build 때 추가 memory mapping 지정
arch/x86/gen_mmu.py는 첫 linker pass가 만든 kernel image를 사용해 code 실행과 data 접근에 필요한 multi-level page table을 생성합니다. Script에 추가 command-line argument를 넘겨 static mapping이나 아주 이른 boot 단계의 device MMIO 접근 mapping을 만들 수 있습니다. Board configuration file의 CMake list X86_EXTRA_GEN_MMU_ARGUMENTS에 값을 넣습니다.
set(X86_EXTRA_GEN_MMU_ARGUMENTS
--map 0xA0000000,0x2000
--map 0x80000000,0x400000,LWUX,0xB0000000)--map 형식은 <physical address>,<size>[,<flags:LUWX>[,<virtual address>]]입니다.
physical address: mapping할 physical address이며 필수입니다.size: mapping할 region 크기이며 필수입니다.flags: 선택 항목입니다. L은 page-directory level large page, U는 userspace 접근, W는 read/write, X는 실행 허용, D는 cache disable입니다.- Flag 기본값은 small page(4KB), supervisor-only, read-only, 실행 불허입니다.
virtual address: mapping할 virtual address이며 선택 항목입니다.
추가 memory mapping은 미리 할당하는 kernel 및 per-domain page table 저장 공간을 늘립니다. CONFIG_X86_EXTRA_PAGE_TABLE_PAGES로 추가 예약 page 수를 정해야 하며, 필요한 크기와 맞지 않으면 gen_mmu.py가 올바른 Kconfig 값을 안내합니다.
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.