hardware/porting/soc_porting.html · hardware/porting/soc_porting.rst 공식 원문 ↗

Zephyr 3.7.0 · Hardware · Porting

SoC 이식 가이드

SoC family와 series부터 CPU cluster까지 hardware 계층을 정의하고 build system에 연결합니다.

Official pathhardware/porting/soc_porting.html
Source filehardware/porting/soc_porting.rst
Source versionZephyr 3.7.0
TranslationFull · reviewed

본문 기준: Zephyr 3.7.0 LTS3 · 이후 유지보수 패치는 별도입니다.

Part 1

요약·해설

고유 SoC 이름과 directory를 만들고 YAML metadata, DTSI hardware, Kconfig symbol·default를 일관되게 구성합니다.

Metadata

family · series · SoC

Hardware

DTSI · CPU clusters

Build

Kconfig · CMake

Part 2

접을 수 있는 영어 원문 전체

영어 원문 전체 펼치기
원문 SHA-256 9312DCDE739B29D79EEEC1A8098D0135E77C78DB1E303BDA0EDE4D5363A2AA61
.. _soc_porting_guide:

SoC Porting Guide
###################

This page describes how to add support for a new :term:`SoC` in Zephyr, be it in
the upstream Zephyr project or locally in your own repository.

SoC Definitions
***************

It is expected that you are familiar with the board concept in Zephyr.
A high level overview of the hardware support hierarchy and terms used in the
Zephyr documentation can be seen in :ref:`hw_support_hierarchy`.

For SoC porting, the most important terms are:

- SoC: the exact system on a chip the board's CPU is part of.
- SoC series: a group of tightly related SoCs.
- SoC family: a wider group of SoCs with similar characteristics.
- CPU Cluster: a cluster of one or more CPU cores.
- CPU core: a particular CPU instance of a given architecture.
- Architecture: an instruction set architecture.

Architecture
============

See :ref:`architecture_porting_guide`.


Create your SoC directory
*************************

Each SoC must have a unique name. Use the official name given by the SoC vendor
and check that it's not already in use. In some cases someone else may have
contributed a SoC with identical name. If the SoC name is already in use, then
you should probably improve the existing SoC instead of creating a new one.
The script ``list_hardware`` can be used to retrieve a list of all SoCs known
in Zephyr, for example ``./scripts/list_hardware.py --soc-root=. --socs`` from
the Zephyr base directory for a list of names that are already in use.

Start by creating the directory ``zephyr/soc/<VENDOR>/soc1``, where
``<VENDOR>`` is your vendor subdirectory.

.. note::
  A ``<VENDOR>`` subdirectory is mandatory if contributing your SoC
  to Zephyr, but if your SoC is placed in a local repo, then any folder
  structure under ``<your-repo>/soc`` is permitted.
  The ``<VENDOR>`` subdirectory must match a vendor defined in the list in
  :zephyr_file:`dts/bindings/vendor-prefixes.txt`. If the SoC vendor does not
  have a prefix in that list, then one must be created.

.. note::

  The SoC directory name does not need to match the name of the SoC.
  Multiple SoCs can even be defined in one directory. In Zephyr, SoCs are often
  organized in sub-folders in a common SoC Family or SoC Series tree.

Your SoC directory should look like this:

.. code-block:: none

   soc/<VENDOR>/<soc-name>
   ├── soc.yml
   ├── soc.h
   ├── CMakeLists.txt
   ├── Kconfig
   ├── Kconfig.soc
   └── Kconfig.defconfig

Replace ``<soc-name>`` with your SoC's name.


The mandatory files are:

#. :file:`soc.yml`: a YAML file describing the high-level meta data of the
   SoC such as:
   - SoC name: the name of the SoC
   - CPU clusters: CPU clusters if the SoC contains one or more clusters
   - SoC series: the SoC series to which the SoC belong
   - SoC family: the SoC family to which the series belong

#. :file:`soc.h`: a header file which can be used to describe or provide
   configuration macros for the SoC. The :file:`soc.h` will often be included in
   drivers, sub-systems, boards, and other source code found in Zephyr.

#. :file:`Kconfig.soc`: the base SoC configuration which defines a Kconfig SoC
   symbol in the form of ``config SOC_<soc-name>`` and provides the SoC name to
   the Kconfig ``SOC`` setting.
   If the ``soc.yml`` describes a SoC family and series, then those must also
   be defined in this file. Kconfig settings outside of the SoC tree must not be
   selected. To select general Zephyr Kconfig settings the :file:`Kconfig` file
   must be used.

#. :file:`CMakeLists.txt`: CMake file loaded by the Zephyr build system. This
   CMake file can define additional include paths and/or source files to be used
   when a build targets the SoC. Also the base line linker script to use must be
   defined.

The optional files are:

- :file:`Kconfig`, :file:`Kconfig.defconfig` software configuration in
  :ref:`kconfig` format. These select the architecture and peripherals
  available.

Write your SoC YAML
*********************

The SoC YAML file describes the SoC family, SoC series, and SoC at a high level.

Detailed configurations, such as hardware description and configuration are done
in devicetree and Kconfig.

The skeleton of a simple SoC YAML file containing just one SoC is:

.. code-block:: yaml

   socs:
   - name: <soc1>

It is possible to have multiple SoC located in the SoC folder.
For example if they belong to a common family or series it is recommended to
locate such SoC in a common tree.
Multiple SoCs and SoC series in a common folder can be described in the
:file:`soc.yml` file as:

.. code-block:: yaml

   family:
     name: <family-name>
     series:
       - name: <series-1-name>
         socs:
           - name: <soc1>
             cpucluster:
               - name: <coreA>
               - name: <coreB>
                 ...
           - name: <soc2>
       - name: <series-2-name>
         ...


Write your SoC devicetree
*************************

SoC devicetree include files are located in the :file:`<zephyr-repo>/dts` folder
under a corresponding :file:`<ARCH>/<VENDOR>`.

The SoC :file:`dts/<ARCH>/<VENDOR>/<soc>.dtsi` describes your SoC hardware in
the Devicetree Source (DTS) format and must be included by any boards which use
the SoC.

If a highlevel :file:`<arch>.dtsi` file exists, then a good starting point is to
include this file in your :file:`<soc>.dtsi`.

In general, :file:`<soc>.dtsi` should look like this:

.. code-block:: devicetree

   #include <arch>/<arch>.dtsi

   / {
           chosen {
                   /* common chosen settings for your SoC */
           };

           cpus {
                   #address-cells = <m>;
                   #size-cells = <n>;

                   cpu@0 {
                   device_type = "cpu";
                   compatible = "<compatibles>";
                   /* ... your CPU definitions ... */
           };

           soc {
                   /* Your SoC definitions and peripherals */
                   /* such as ram, clock, buses, peripherals. */
           };
   };

.. hint::
   It is possible to structure multiple :file:`<VENDOR>/<soc>.dtsi` files in
   sub-directories for a cleaner file system structure. For example organized
   pre SoC series, like this: :file:`<VENDOR>/<SERIES>/<soc>.dtsi`.


Multiple CPU clusters
=====================

Devicetree reflects the hardware. The memory space and peripherals available to
one CPU cluster can be very different from another CPU cluster, therefore each
CPU cluster will often have its own :file:`.dtsi` file.

CPU cluster :file:`.dtsi` files should follow the naming scheme
:file:`<soc>_<cluster>.dtsi`. A :file:`<soc>_<cluster>.dtsi` file will look
similar to a SoC :file:`.dtsi` without CPU clusters.

Write Kconfig files
*******************

Zephyr uses the Kconfig language to configure software features. Your SoC
needs to provide some Kconfig settings before you can compile a Zephyr
application for it.

Setting Kconfig configuration values is documented in detail in
:ref:`setting_configuration_values`.

There is one mandatory Kconfig file in the SoC directory, and two optional
files for a SoC:

.. code-block:: none

   soc/<vendor>/<your soc>
   ├── Kconfig.soc
   ├── Kconfig
   └── Kconfig.defconfig

:file:`Kconfig.soc`
  A shared Kconfig file which can be sourced both in Zephyr Kconfig and sysbuild
  Kconfig trees.

  This file selects the SoC family and series in the Kconfig tree and potential
  other SoC related Kconfig settings. In some cases a SOC_PART_NUMBER.
  This file must not select anything outside the re-usable Kconfig SoC tree.

  A :file:`Kconfig.soc` may look like this:

  .. code-block:: kconfig

     config SOC_<series name>
             bool

     config SOC_<SOC_NAME>
             bool
             select SOC_SERIES_<series name>

     config SOC
             default "SoC name" if SOC_<SOC_NAME>

  Notice that ``SOC_NAME`` is a pure upper case version of the SoC name.

  The Kconfig ``SOC`` setting is globally defined as a string and therefore the
  :file:`Kconfig.soc` file shall only define the default string value and not
  the type. Notice that the string value must match the SoC name used in the
  :file:`soc.yml` file.

:file:`Kconfig`
  Included by :zephyr_file:`soc/Kconfig`.

  This file can add Kconfig settings which are specific to the current SoC.

  The :file:`Kconfig` will often indicate given hardware support using a setting
  of the form ``HAS_<support>``.

  .. code-block:: kconfig

     config SOC_<SOC_NAME>
             select ARM
             select CPU_HAS_FPU

  If the setting name is identical to an existing Kconfig setting in Zephyr and
  only modifies the default value of said setting, then
  :file:`Kconfig.defconfig` should be used  instead.

:file:`Kconfig.defconfig`
  SoC specific default values for Kconfig options.

  Not all SoCs have a :file:`Kconfig.defconfig` file.

  The entire file should be inside a pair of ``if SOC_<SOC_NAME>`` / ``endif``
  or ``if SOC_SERIES_<SERIES_NAME>`` / ``endif``, like this:

  .. code-block:: kconfig

     if SOC_<SOC_NAME>

     config NUM_IRQS
             default 32

     endif # SOC_<SOC_NAME>

Multiple CPU clusters
=====================

CPU clusters must provide additional Kconfig settings in the :file:`Kconfig.soc`
file. This will usually be in the form of ``SOC_<SOC_NAME>_<CLUSTER>`` so for
a given ``soc1`` with two clusters ``clusterA`` and ``clusterB``, then this
will look like:

SoC's When a SoC defines CPU cluster

  .. code-block:: kconfig

     config SOC_SOC1_CLUSTERA
             bool
             select SOC_SOC1

     config SOC_SOC1_CLUSTERB
             bool
             select SOC_SOC1

Part 3

한국어 전문 번역

이 문서는 upstream Zephyr project 또는 local repository에 새 SoC 지원을 추가하는 방법을 설명합니다.

SoC Definitions

Zephyr board 개념과 hardware support hierarchy에 익숙하다고 가정합니다. SoC porting에서 중요한 용어는 다음과 같습니다.

  • SoC: Board CPU가 속한 정확한 system-on-chip
  • SoC series: 서로 밀접한 SoC 묶음
  • SoC family: 비슷한 특성을 공유하는 더 넓은 SoC 묶음
  • CPU cluster: CPU core 하나 이상의 cluster
  • CPU core: 특정 architecture의 개별 CPU instance
  • Architecture: Instruction set architecture

Architecture

새 architecture 지원은 Architecture Porting Guide를 참고합니다.

Create your SoC directory

각 SoC에는 고유한 이름이 필요합니다. Vendor의 공식 이름을 사용하고 이미 쓰이는지 확인합니다. 같은 이름의 SoC가 이미 contribution됐다면 새로 만들기보다 기존 지원을 개선하는 편이 좋습니다.

list_hardware script로 Zephyr가 아는 SoC를 확인할 수 있습니다. Zephyr base directory에서 ./scripts/list_hardware.py --soc-root=. --socs를 실행하면 사용 중인 이름을 나열합니다.

zephyr/soc/<VENDOR>/soc1 directory를 만드는 것으로 시작합니다.

SoC directory의 기본 구조는 다음과 같습니다.

soc/<VENDOR>/<soc-name>
├── soc.yml
├── soc.h
├── CMakeLists.txt
├── Kconfig
├── Kconfig.soc
└── Kconfig.defconfig

<soc-name>은 실제 SoC name으로 바꿉니다.

필수 file은 다음과 같습니다.

  1. soc.yml: SoC name, 선택적인 CPU cluster, series, family 같은 high-level metadata를 기술합니다.
  2. soc.h: SoC configuration macro를 기술·제공하는 header입니다. Driver, subsystem, board와 다른 Zephyr source에서 자주 include합니다.
  3. Kconfig.soc: config SOC_<soc-name> 형태의 SoC symbol을 정의하고 Kconfig SOC setting에 SoC name을 제공합니다. YAML이 family·series를 기술한다면 여기에도 정의합니다. 재사용 가능한 SoC tree 밖의 일반 Zephyr setting은 선택하지 말고 Kconfig에서 선택합니다.
  4. CMakeLists.txt: Build가 SoC를 target할 때 추가 include path·source file과 baseline linker script를 정의합니다.

Kconfig와 Kconfig.defconfig는 architecture와 사용 가능한 peripheral을 선택하는 optional software configuration입니다.

Write your SoC YAML

SoC YAML은 family, series, SoC를 high level에서 설명합니다. 구체적인 hardware description과 configuration은 Devicetree와 Kconfig에 둡니다.

SoC 하나만 있는 단순 skeleton은 다음과 같습니다.

socs:
- name: <soc1>

같은 folder에 SoC를 여러 개 둘 수 있습니다. 공통 family·series에 속한다면 같은 tree에 배치하는 것을 권장하며 `soc.yml`은 다음처럼 여러 series·SoC·CPU cluster를 설명할 수 있습니다.

family:
  name: <family-name>
  series:
    - name: <series-1-name>
      socs:
        - name: <soc1>
          cpucluster:
            - name: <coreA>
            - name: <coreB>
              ...
        - name: <soc2>
    - name: <series-2-name>
      ...

Write your SoC devicetree

SoC Devicetree include file은 <zephyr-repo>/dts/<ARCH>/<VENDOR> 아래에 둡니다. dts/<ARCH>/<VENDOR>/<soc>.dtsi가 SoC hardware를 DTS 형식으로 기술하고 이 SoC를 사용하는 모든 board가 include해야 합니다.

<arch>.dtsi 같은 high-level architecture include가 있다면 <soc>.dtsi에서 이를 include하는 것이 좋은 시작점입니다.

일반적인 SoC DTSI 구조는 다음과 같습니다.

#include <arch>/<arch>.dtsi

/ {
        chosen {
                /* common chosen settings for your SoC */
        };

        cpus {
                #address-cells = <m>;
                #size-cells = <n>;

                cpu@0 {
                device_type = "cpu";
                compatible = "<compatibles>";
                /* ... your CPU definitions ... */
        };

        soc {
                /* Your SoC definitions and peripherals */
                /* such as ram, clock, buses, peripherals. */
        };
};

Multiple CPU clusters

Devicetree는 실제 hardware를 반영합니다. CPU cluster마다 접근 가능한 memory와 peripheral이 크게 다를 수 있으므로 각 cluster가 별도 `.dtsi` file을 갖는 경우가 많습니다.

CPU-cluster DTSI는 <soc>_<cluster>.dtsi naming scheme을 따릅니다. 내용은 CPU cluster가 없는 일반 SoC DTSI와 비슷합니다.

Write Kconfig files

Zephyr는 Kconfig로 software feature를 구성합니다. SoC를 target한 application을 compile하기 전에 SoC가 필요한 설정을 제공해야 합니다.

SoC directory에는 필수 Kconfig file 하나와 optional file 두 개가 있습니다.

soc/<vendor>/<your soc>
├── Kconfig.soc
├── Kconfig
└── Kconfig.defconfig

Kconfig.soc는 Zephyr와 sysbuild Kconfig tree가 모두 source할 수 있는 shared file입니다. SoC family·series와 그 밖의 SoC 관련 setting, 필요하면 SOC_PART_NUMBER를 선택합니다. 재사용 가능한 Kconfig SoC tree 밖의 symbol을 선택하면 안 됩니다.

config SOC_<series name>
        bool

config SOC_<SOC_NAME>
        bool
        select SOC_SERIES_<series name>

config SOC
        default "SoC name" if SOC_<SOC_NAME>

SOC_NAME은 SoC name을 순수 대문자로 바꾼 값입니다. Global Kconfig SOC는 이미 string type으로 정의돼 있으므로 Kconfig.soc는 type을 다시 정의하지 않고 default string만 설정합니다. 그 string은 soc.yml의 SoC name과 정확히 같아야 합니다.

Kconfig는 soc/Kconfig에서 include하며 current SoC 전용 setting을 추가합니다. Hardware 지원 여부는 보통 HAS_<support> 형태로 나타냅니다.

config SOC_<SOC_NAME>
        select ARM
        select CPU_HAS_FPU

기존 Zephyr symbol의 default만 바꾼다면 `Kconfig` 대신 `Kconfig.defconfig`를 사용합니다.

Kconfig.defconfig는 SoC별 default value를 설정하는 optional file입니다. 전체 file을 if SOC_<SOC_NAME> 또는 if SOC_SERIES_<SERIES_NAME>와 endif로 감쌉니다.

if SOC_<SOC_NAME>

config NUM_IRQS
        default 32

endif # SOC_<SOC_NAME>

Multiple CPU clusters

CPU cluster는 Kconfig.soc에 보통 SOC_<SOC_NAME>_<CLUSTER> 형태의 추가 symbol을 제공해야 합니다. soc1의 clusterA와 clusterB 예는 다음과 같고, 각 cluster symbol은 parent SOC_SOC1을 select합니다.

config SOC_SOC1_CLUSTERA
        bool
        select SOC_SOC1

config SOC_SOC1_CLUSTERB
        bool
        select SOC_SOC1

Source

출처

영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.