원문
본 블로그 내용은 "A step-by-step guide to bringing up your NXP i.MX8"를 필요에 의해 번역한 것 이다.
Human Machine Interface(HMI)는 산업 자동화의 가장 중요한 기술 중 하나가 되었다. 따라서 인간과 머신 사이의 상호 작용을 용이하게 하는 것을 목표로 하는 혁신적인 플랫폼을 내놓는 회사를 보는 것은 더 이상 놀라운 일이 아니다. 소프트웨어 또는 디바이스일 수 있는, HMI로 사용자는 머신과 효울적으로 통신할 수 있다. 따라서 산업 자동화 환경에서 그 인기는 꽤 타당해 보인다.
HMI in Industrial Automation (산업 자동화의 HMI)
I/O, SoftPlc CoDeSys나 Ethercat 그리고 Embedded Operating System과 같은 리소스로 사용자는 모든 생산 시스템과 통신할 수 있으므로, 애플리케이션의 시각화와 컨트롤이 가능하다. 일반적으로 HMI 디바이스는 산업 플랜트의 요구 사항에 맞게 제작된다. 따라서 HMI는 프로세서, 연결성, 메모리, 디스플레이 기술 등에서 매우 다양할 수 있다. HMI는 다양한 형태, 모양 그리고 크기로 제공된다. 컴퓨터 모니터나 머신의 내장 스크린이나 태블릿에서 찾을 수 있다.
산업 환경에서, 산업 자동화의 HMI는 주로 다음 용도로 사용된다. I/O 모니터링, 데이터 시각화, 생산 시간, 추세 그리고 태그 등을 추적한다.
Role of i.MX8 in HMI for Industrial Automation (산업 자동화용 HMI에서 i.MX8의 역할)
i.MX8이 산업용 HMI에 이상적인 이유는 무엇일까?
- 하나의 단일 프로세서로 여러 플랫폼과 여러 운영 체제를 수용할 수 있다.
- SECO HSM으로 탁월한 보안을 제공한다.
- FDSOI로 시스템의 안정성을 향상한다.
- 고급 비전 기반의 HMI를 만들 수 있다.
i.MX8 프로세서는 NXP의 최신 i.MX 프로세서 시리즈이다. i.MX8의 주요 컴포넌트는 System Control Unit(SCU), Cortex-A 기반 멀티 코어 애플리케이션 프로세서, Cortex-M 기반 애플리케이션 프로세서와 이미지, 비디오 그리고 그래픽 처리를 위한 전용 프로세서이다.
System Control Unit(SCU)와 Cortex-A 및 Cortex-M4 기반의 두 개의 애플리케이션 플랫폼이 주요 컴포넌트이다. SCU 자체에는 보안 관련 기능을 수행하는 전용 SECO(Security Controller: 보안 컨트롤러)인 Cortex-M4 프로세서와 같은 여러 컴포넌트가 포함되어 있다. SCU는 시스템을 부팅하고 전원/클럭을 관리하며, 내부의 서브 시스템의 재설정을 담당한다. i.MX8을 고성능 애플리케이션에 적합하게 만드는 것은 멀티코어 Cortex-A 프로세서의 존재이다. 또한, 멀티미디어 프로세어의 존재로 고급 그래픽, 이미지, 오디오, 음성과 비디오 애플리케이션에 적합하다. 따라서 i.MX8 제품군 프로세서는 전 세계 다양한 산업에서 사용된다. 여기에서 i.MX6 기반의 많은 제품이 i.MX8 플랫폼으로 포팅되고 있음을 알 수 있다.
PathPartner는 i.MX8로 강력한 애플리케이션을 구축할 수 있도록 지원한다. i.MX8 아키텍처에 대한 일련의 기사 중 첫 번째로 사용자 보드 브링업에 대한 정보를 제공한다. 이 문서는 각 부트 단계와 관련된 i.MX8 부트 아키텍처와 소프트웨어 컴포넌트를 이해하는 데 도움이 된다.
Board Bringup for Custom Boards on i.MX8 (i.MX8에서 사용자 보드를 위한 보드 브링업)
i.MX8에는 여러 부팅 단계가 있으므로, 보드 브링업은 다양한 레벨에서 수행이 필요하다. 그러나 전체 부팅 프로세스를 자세히 검토하는 것은 이 문서의 범위를 벗어나므로, NXP 커뮤니티에서 해당 문서를 참조할 수 있다. 이 문서는 주로 DDR, eMMC, SCFW, uBoot 그리고 Kernel과 같은 인터페이스의 브링업에 중점을 둔다.
다음 블럭 다이어그램은 사용자 보드를 브링업하는 동안 필요한 최소 인터페이스(또는 주변 장치)를 보여준다. 이러한 모듈은 브링업 프로세스의 일부로서 브링업해야 한다.
Understanding i.MX8 Boot Flow Sequence (i.MX8 부트 흐름 순서의 이해)
아래 다이어그램은 i.MX8 플랫폼의 기본적인 부트 흐름을 보여준다. Power-on-Reset 이후, i.MX8 ROM 부트로더는 실행되는 첫 번째 소프트웨어이다. ROM 부트로더에는 SCU ROM와 SECO ROM이라는 두 개의 개별 이미지가 있다.
i.MX8 Software Components (i.MX8 소프트웨어 컴포넌트)
이제 부트 흐름 순서에 대한 기본적인 이해를 바탕으로 부트 프로세스와 관련된 다양한 소프트웨어 컴포넌트를 살펴본다. SCFW와 SECO 다음으로 Cortex-A/M4 이미지가 나타난다. 의도된 애플리케이션을 기반으로 Cortex-A나 Cortex-M4 또는 둘 다 함께 사용할 수 있다. 이 문서는 Cortex-A 부팅에만 초점을 맞추므로 Cortex-M4는 사용하지 않는다.
Cortex-A 이미지는 uboot라는 기본 부트로더에 불과하다. Arm Trusted Firmware(NXP에서 제공하는 bl31.bin)라는 또 다른 소프트웨어 컴포넌트는 uboot를 사용할 때 그림에 나타난다.
소프트웨어 컴포넌트를 요약하면,
- SCFW - System Controller Firmware 바이너리
- SECO FW - Security Controller Firmware
- bl31.bin - ARM Trusted Firmware (ATF)
- u-boot.bin - Cortext-A용 U-boot 바이너리
위에서 언급된 소프트웨어 컴포넌트는 flash.bin이라는 단일 부팅 가능 이미지로 함께 추가된다. NXP는 위에서 언급한 모든 이미지를 병합하여 부팅 가능한 이미지를 생성하는 도구(mkimage 도구)를 제공한다. 위에서 설명된 이미지와 함께 flash.bin은 모든 이미지를 각 코어/메모리에 로드/인증하는 데 필요한 여러 정보(각 이미지에 대한 이미지 오프셋, 크기, 로드 주소, 진입점과 같은 데이터)를 포함하고, SCFW 실행 동작을 컨트롤하는 플래그도 포함한다. 그러나 이 문서에서는 부팅 가능한 이미지(부트 컨테이너라고도 함) 내부에 무엇이 있는지에 대한 자세한 설명은 다루지 않는다. 이 부팅가능한 이미지는 eMMC/SD 카드로 로드할 수 있다.
다음 질문, eMMC/SD 카드에서 flash.bin을 어디에 로드할까요(이 문서에서 설명하는 내용은 eMMC/SD 카드 부팅으로 제한됨)? 그것은 NXP에서 언급한 특정 위치가 될 것이다.
아래 테이블은 flash.bin을 로드할 위치를 보여준다.
Boot Device | Image Offset |
---|---|
SD | 32KB |
eMMC | 0, Boot Partition 32KB에 위치되는 경우, User Area에 위치되는 경우. |
그러나, 아직 보드를 부팅할 준비가 되지 않은 상태에서 eMMC에 어떻게 저장할 수 있을 까요? 보드를 브링업하는 동안, 부팅 가능한 디바이스로 SD 카드를 사용하는 것이 좋다. 위에서 제공된 지침으로, flash.bin은 SD 카드의 32KB 오프셋에 복사될 수 있다.
이제 SD 카드에 부팅 가능한 이미지가 준비되었으므로, 이 부팅 가능한 카드를 하드웨어의 SD 카드 슬롯에 장착할 수 있다. ROM 부트로더는 SD 카드에서 falsh.bin 이미지를 읽고 SCFW와 SECO FW를 SCU로 로드하는 역할을 한다.
Considerations Required for Customization (사용자 정의에 필요한 고려 사항)
이전 섹션으로 부팅 단계, 소프트웨어 컴포넌트와 새로운 신규 보드를 플래시하는 방법에 대해 익숙해졌다. 이제 이를 사용하여 사용자 정의 보드를 부팅하는 방법을 살펴본다. 사용자 정의해야 하는 컴포넌트는 무엇인가요? 소프트웨어를 사용자 정의할 때, 염두에 두어야 할 몇 가지 기본적인 사항이 있다.
- NXP에서 제공하는 SECO FW와 Arm Trusted Firmware는 바로 사용할 수 있다.
- SCFW 사용자 정의 - NXP의 레퍼런스 EVK에서 핵심 주요 신호를 변경했나요? HW 구성을 결정하기 위한 지능형 로직을 구현하고 싶나요?
- DCD 파일 사용자 정의 - 레퍼런스 EVK에서 DDR을 변경했나요? u-Boot에서 고려해야 할 몇 가지 인수를 업데이트/초기화하고 싶나요?
- 디버그 콘솔로 상용되는 시리얼 포트의 적절한 구성.
- 다음 레벨의 펌웨어 로딩(이 경우 커널)을 위해 필요한 인터페이스(eMMC/SD 인터페이스) 구성.
i.MX8 Power checkup (i.MX8 전원 점검)
ROM에서 부팅의 첫 번째 단계가 발생하므로 사용자 정의가 필요하지 않다. 그러나 ROM 부트로더가 올바르게 부팅되려면, i.MX8에 적절한 전원이 공급되어야 한다. 이는 일반적으로 하드웨어 엔지니어의 책임으로, 사용자 정의 보드의 전원 회로가 적절하게 디자인되고 검증되었는지 확인해야 한다.
시스템의 다양한 영역에 대한 전원 분배를 관리하기 위해, PMIC는 i.MX8 전원 회로의 주요 컴포넌트 중 하나이다. PMIC는 Cortex-A/M4 코어, GPU, DDR 그리고 기타 주변 장치를 포함하여, 다양한 주변 장치/서브시스템에 다양한 전압의 전원 공급을 제공한다. 따라서 온전한 시스템 부팅을 위해, 각 주변 장치/서브시스템에서 필요로 하는 전압 레벨을 사용할 수 있는지 확인해야 한다.
About DDR Configuration (DDR 구성에 대해)
i.MX8에 적절한 전원이 공급되면, ROM 부트로더가 부팅되어 SCFW를 TCM으로 로드하고 Cortex-A/M4 이미지를 DDR 메모리로 로드한다. Cortex-A/M4 이미지를 DDR 메모리로 로드하기 전에, DDR은 올바르게 구성되어야 하고 이는 SCU ROM에서 수행된다. 그러나 DDR은 어떻게 구성되나요? DDR 구성은 DCD 파일이라는 파일에서 사용할 수 있으며 SCFW의 일부이다. SCU ROM은 이 파일을 읽고 DDR을 구성한다. 따라서 DDR에 필요한 모든 사용자 정의를 DCD 파일에 수용할 수 있다.
사용해야 하는 DDR 메모리가 다른 경우, DDR 구성을 정의하는 DCD 파일을 수정해야 할 수 있다. DDR 구성을 위해, NXP는 Excel 시트 형식으로 DDR Register Programming Aid(RPA)를 제공한다. 사용자는 RPA 레지스터 구성 워크시트 탭에서 Device 정보 테이블을 업데이트해야 한다. Device 정보를 입력하면, 동일한 워크시트 탭에서 구성 값이 자동으로 계산된다. 이것은 기본 DDR 구성으로 사용할 수 있다. RPA에 대한 문서 중 하나는 여기에서 찾을 수 있다.
또한, DDR 타이밍은 DDR 스트레스 테스트 도구를 사용하여 미세 조정할 수 있다. DDR 구성에 대한 자세한 내용은 BSP 포팅 가이드의 섹션 3.2.1을 참조한다.
Understanding SPL Boot Flow (SPL 부트 흐름 이해)
대부분의 사용자 정의 하드웨어의 경우, NXP에서 제공하는 SCFW가 사용될 수 있다. SCFW에 대한 사용자 정의가 필요한 경우, Advanced SCFW 문서를 참조한다. 그러나 Special 부트 흐름(Boot Flow 섹션에서 논의한 것과 대조되는)에 대해 논의하고 싶다. Boot Flow 섹션에서 논의한 것처럼, DDR 초기화는 SCU ROM에서 수행되며, 이는 사용자가 DDR 초기화를 컨트롤할 수 없음을 의미한다. 경우에 따라 SCU ROM에서 수행하는 대신 SCFW(사용자가 사용자 지정할 수 있는)에서 DDR 초기화를 수행하려는 경우, Special(SPL) 부트 흐름이라는 옵션이 NXP에 있다.
SPL Boot Flow를 사용하고 있다면, DDR이 SCU ROM에서 초기화되지 않은 것이 분명하다. 그렇다면 애플리케이션(Cortex-A) 이미지를 DDR의 초기화 없이 DDR에 로드하려면 어떻게 해야 할까요? SPL Boot Flow에서 SPL 이미지(Cortex-A uboot 이미지의 일부가 되는)는 SCFW에서 Cortex-A 코어를 활성화한 후 애플리케이션 이미지를 DDR로 로드하는 작업을 처리한다. 따라서 SCU ROM은 SCFW와 SECO FW를 메모리에 로드하는 역할만 한다.
SPL Boot Flow를 어떻게 활성화하나요? 따라야 할 작업 단계는 무엇인가요?
답은 부팅 가능한 이미지를 생성하는 동안 수행되어야 한다는 것이다. SCU ROM은 Non-SPL Boot 모드에서 DDR 초기화를 수행하지만, 초기화를 수행하는 API는 SCFW 보드 파일에 정의되어 있다. 보드 파일은 platform/board/mx8*/ 디렉토리에 있다. 사용된 API는 board_init_ddr()이며, 내부에서 board_ddr_config()를 호출한다. 다음은 SPL Boot 모드를 활성화하는 데 필요한 단계이다.
- SKIP_DDR inboard.h 파일을 정의한다. 이렇게 하면 SCU ROM 실행 중에 DDR 초기화를 건너뛸 수 있다. 어떻게 작동하는지 알아보려면, board_init_ddr() API inboard.c를 참조한다.
- board_ddr_config() API에서 #include “dcd/dcd.h”를 제거한다.
- board_init_ddr() API의 복사본을 만들고, board_init_ddr_custom()와 같은 이름으로 변경한다. 또한 board_init_ddr_custom() API에서 SKIP_DDR이 포함된 섹션을 제거한다.
- board_system_config() API에서 #include "dcd/dcd.h"와 board_init_ddr_custom()을 호출한다. board_system_config()는 SCFW에서 사용된다.
- 마지막으로 imx-mkimage 유틸리티에 flash_spl라고 부르는 추가 인수를 사용하여 부팅 가능한 이미지(flash.bin)를 빌드한다. make 옵션의 예는 다음과 같다: make SOC=iMX8QX flash_spl (i.MX8QXP용)
부트 시퀀스에서 공유된 것처럼, 일단 BOOTROM 코드에서 사용자 정의 빌드 소프트웨어 컴포넌트로 이동하면 고급 소프트웨어 컴포넌트(uBoot와 Kernel을 더 쉽게 )를 브링업 할 수 있다. 사용자 정의와 브링업은 <place holder for uBoot and kernel bringup>에서 설명한다.
About Uboot bring-up (UBoot 브링업에 대해)
NXP의 Uboot 소스 코드는 imx8qm_mek, imx8qxp_mek 등과 같은 i.MX8 기반의 여러 레퍼런스 보드를 지원한다. i.MX 레퍼런스 보드파일은 아래 나열된 여러 디렉토리에 있다.
- 구성 파일(defconfig 파일)은 configs/ 디렉토리에서 사용할 수 있다.
- 보드 파일 inboard/freescale/
- include/configs/의 보드 구성 파일
사용자 정의 보드에 가장 적합한 레퍼런스 보드(NXP에서 제공)를 확인해야 한다. 위의 디렉토리에서 파일(레퍼런스 보드와 일치하는)을 복제하고 사용자 정의 보드와 일치하도록 이름을 변경한다. 이제 하드웨어 디자인을 기반으로 사용자 정의를 진행할 수 있는 파일이 있다.
예를 들어, imx8qxp_mek 레퍼런스 보드의 복사본을 만들어 본다. Files/Directories는 복제해야 한다.
- configs/imx8qxp_mek_defconfig
- arch/arm/dts/fsl-imx8qxp-mek.dts
- board/freescale/imx8qxp_mek/ 디렉토리
- include/configs/imx8qxp_mek.h 파일
아래와 같이 복제할 수 있다.
- configs/imx8qxp_cutsom_defconfig
- arch/arm/dts/fsl-imx8qxp-custom.dts
- board/freescale/imx8qxp_custom/ 디렉토리
- include/configs/imx8qxp_custom.h 파일
Board file customization (보드 파일 사용자 지정)
보드 브링업의 초기 단계에서, 시스템에서 무슨일이 일어나고 있는지 아는 것이 중요하다. 따라서 시리얼 디버그 콘솔을 먼저 브링업해야 한다. 그렇다면 시리얼 포트를 작동시키려면 어떤 사용자 정의를 수행해야 할까요?
Uboot는 3단계로 초기화를 제공한다. 이러한 초기화는 imx8qxp_custom.c 파일에서 사용할 수 있다.
CONFIG_BOARD_EARLY_INIT_F를 정의하면, 초기 단계(early phase)에서 board_early_init_f() 함수가 호출된다. 이 함수에서 UART(디버그 콘솔에 사용되는)의 pin mux 구성을 정의한다. 대부분의 NXP 레퍼런스 보드 파일에는 이미 이 초기화가 포함되어 있다. 이 단계에서 올바른 UART 인터페이스(회로도 확인)가 초기화되었는지 확인해야 한다. 이를 통해, 최소한 uboot까지 보드가 부팅되도록 최소한의 변경만 진행했다.
초기화 함수의 두 단계는 board_init()와 board_late_init()이다. 필요한 기능(예: Ethernet , GPIO 등)에 대한 드라이버 초기화를 넣을 수 있다.
Defconfig customization (defconfig 사용자 정의)
defconfig는 이 단계에서 사용자 지정할 필요가 없다. 기본적인 브링업이 완료되면, 필요한 기능에 따라 enable/disable하도록 사용자 정의할 수 있다. 단, 브링업에 필요한 기능이 활성화되어 있는지 확인해야 한다.
DTS customization (DTS 사용자 정의)
디바이스 트리는 필요한 인터페이스에 대한 드라이버를 활성화하고 인터페이스에 대한 pin mux 구성을 수행하는 데 사용된다. uboot의 역할은 커널 이미지를 로드하도록 시스템을 준비하는 것이다.
그렇다면, 이를 위해 어떤 것들을 사용자 정의해야 할까요? Kernel 이미지는 eMMC/SD 카드의 파티션 중 하나에 배치된다. 이런 이유로, uboot에서 초기화해야 하는 기본적인 인터페이스는 SDHC 인터페이스라고 하는 eMMC/SD 카드 인터페이스이다. 따라서 디바이스 트리 파일에 필요한 사용자 정의는 eMMC/SD 카드 인터페이스용 SDHC 드라이버가 활성화되었는지 확인하는 것이다. 또한 관련된 하드웨어 라인에 대해서는 pin mux 구성을 넣을 것이다. 이러한 변경을 하기 전에 프로토콜과 통신 방식을 이해하기 위한 기본적인 조사를 수행해야 한다.
이제 uBoot는 적절한 드라이버를 사용하여 eMMC/SD 카드와 통신할 준비가 되어 있다.
Board config file customization (보드 구성 파일 사용자 정의)
eMMC/SD 카드 인터페이스가 작동하더라도, 미디어에서 커널 이미지와 커널 dtb를 읽어야 하는 위치를 어떻게 알 수 있나요? 이 정보는 구성 파일에 추가할 수 있다. 보드 구성 파일의 코드 스니펫을 살펴보면,
#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC2 */
#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 /* Partition-1 */
#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */
"image=kernel.bin\0" \
"console=ttyLP0\0" \
"earlycon=lpuart32,0x5a060000\0" \
"fdt_addr=0x83000000\0" \
"fdt_high=0xffffffffffffffff\0" \
"fdt_file=fsl-imx8qxp-mek.dtb\0" \
"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
"mmcargs=setenv bootargs console=${console},${baudrate} earlycon=${earlycon},${baudrate} root=${mmcroot}\0 " \
"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
- mmcdev - eMMC/SD 카드 중에서 선택한다. USDHC1은 eMMC에 사용되며 USDHC2는 SD 카드에 사용된다. 요구 사항에 따라 올바르게 선택해야 한다. 그러나 브링업 단계에서는 SD 카드 인터페이스를 사용하는 것이 좋다.
- mmcpart - 커널 이미지를 로드할 수 있는 파티션을 나타낸다. partition-1에 커널 이미지와 dtb를 넣는다.
- image - 커널 이미지 파일 이름
- fdt_file - dtb 파일 이름
- loadimage - 커널 이미지를 로드하는 커맨드
- loadfdt - dtb 파일을 로드하는 커맨드
loadimage와 loadfdt가 fatload 커맨드를 사용하여 커널과 dtb를 로드하는 것을 알았다면, kernel & dtb가 복사된 파티션이 FAT로 포맷되어 있는지 확인해야 한다. 파티션을 EXT4로 하는 경우, fatload를 ext2load로 변경할 수 있다.
위에서 언급된 파라미터는 커널 이미지와 dtb를 메모리로 읽도록 uboot를 설정한다. 이제 커널 실행을 시작하기 전에, uboot에서 커널로 일부 파라미터를 전달할 수 있다. 전달할 기본적인 파라미터는 다음과 같다.
- console - 시리얼 디버그 콘솔을 나타낸다. 커널 부팅 중에 디버그 출력을 볼 수 있도록, 적절한 콘솔 파라미터가 설정되어 있는지 확인한다.
- mmcroot - 루트 파일 시스템(RFS) 파티션을 정의한다. 커널은 이 정보를 사용하여 RFS를 로드한다.
이러한 파라미터는 bootargs로 전달된다(위 코드 스니펫의 mmcargs 참조). 이 방법으로 모든 정보를 uboot에서 커널로 전달할 수 있다. 예를 들어, 하드웨어에서 uboot에 의해 이미 검색된 모든 보드 관련 정보를 커널로 전달할 수 있다.
보드 구성 파일에는 DDR 위치와 크기에 대한 구성 정보도 포함되어 있다. 이러한 구성이 사용자 정의 하드웨어와 일치하는지 확인한다. iMX8QXP MEK 보드 구성 파일의 DDR 구성 정보는 다음과 같다.
#define CONFIG_SYS_SDRAM_BASE 0x80000000
#define CONFIG_NR_DRAM_BANKS 4
#define PHYS_SDRAM_1 0x80000000
#define PHYS_SDRAM_2 0x880000000
#define PHYS_SDRAM_1_SIZE 0x80000000 /* 2 GB */
/* LPDDR4 board total DDR is 3GB */
#define PHYS_SDRAM_2_SIZE 0x40000000 /* 1 GB */
Kernel bringup (커널 브링업)
커널 브링업은 주로 디바이스 트리 파일을 사용자 정의하는 것과 관련된다. uboot에서 했던 것처럼, 레퍼런스 보드의 디바이스 트리 중 하나를 복사본으로 만들 수 있다. 따라서 arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi의 복사본을 만들고 이름을 arch/arm64/boot/dts/freescale/fsl-imx8qxp-custom.dtsi로 변경한다.
디바이스 트리에서 필요한 최소 driver/pinmux 구성은 eMMC/SD, UART(디버그) 인터페이스이다. 이렇게 하면, 사용자가 콘솔에서 디버그 출력을 얻을 수 있다. 또한, 커널은 eMMC/SD 메모리에 액세스하고 이전 섹션에서 지정한 대로 파티션에서 RFS를 로드할 수 있다.
커널 브링업의 다음 단계는 사용자 정의 보드의 i.MX8 프로세서에 연결된 모든 디바이스가 작동하는지 확인하는 것이다. 이는 적절한 디바이스 트리 노드를 활성화하기 위해 디바이스 트리를 수정하고, 관련된 모든 하드웨어 라인에 대해 올바른 pin mux 구성을 정의하는 것으로 달성할 수 있다. 이 부분은 모든 플랫폼에 대해 일반적이므로 자세한 내용은 다루지 않는다. 그러나 사용자 정의 보드를 브링업하면서 직면하는 근본적인 문제 중 하나를 공유하고 싶다.
우리가 직면한 대부분의 문제는 wrong(잘못된)/missing(누락된) 인터페이스 구성이나 하드웨어 버그이다.
Unable to get serial console login access (시리얼 콘솔 로그인 액세스 권한을 얻을 수 없는 경우)
커널이 RFS를 로드한 후, 시리얼 콘솔 로그인 액세스를 얻기 위해 로그인 서비스가 실행된다. 시스템에 대한 액세스 권한이 없으면, 브링업 동안 디버그하기가 어렵다.
누락된 부분은 UART 구성이었다. 우리가 사용한 레퍼런스 코드에는 시리얼 콘솔로 활성화된 다른 UART 포트(UART0)가 있었다. 그러나 우리의 사용자 정의 보드는 UART1을 사용하고 있었다. 따라서 UART1 디바이스 트리 노드를 올바르게 활성화하고 구성해야 한다. 또한 모든 UART 라인에 대한 pin mux 구성이 제대로 수행되었는지 확인해야 한다. 구성을 수행하는 동안 항상 하드웨어 회로도를 확인한다. UART 라인에는 하드웨어 디자인에 따라 RX/TX 라인과 별도로 RTS/CTS 라인이 포함될 수 있다.
우리가 직면한 다른 많은 문제가 있지만, 대부분은 하드웨어 버그와 관련이 있다. 이 문서에서 모든 문제를 설명하지는 않겠다. 그러나 모든 하드웨어 인터페이스를 디버깅 때 가장 중요한 것은 먼저 프로토콜을 이해하는 것임을 항상 명심해야 한다. 또한 idle과 run-time 중에 모든 하드웨어 라인이 제대로 작동하는지 확인해야 한다. 해피 디버깅 :)
About eMMC Booting (eMMC 부팅에 대해)
지금까지 SD 카드에서 부팅하는 방법에 대해 살펴보았다. 브링업이 완료되면, eMMC로 이동하여 부팅할 수 있다.
ROM 부트로더는 적절한 부트 모드 선택으로 eMMC에서 Uboot 이미지 부팅을 처리한다. eMMC에는 빠른 부트라고 하는 부트 파티션(mmcblk0boot0/mmcblk0boot1)이나 사용자 파티션(mmcblk0)에서 부팅하는 옵션이 있다. 빠른/일반 부트 선택에 대한 자세한 내용은 eMMC Fast Boot in i.MX 8X를 참조한다.
이제 eMMC에서 커널을 부팅하고 RFS를 로드하려면, uboot 레벨에서 구성을 수행해야한다. 이를 위해 uboot 보드 구성 파일을 사용자 정의해야 한다. eMMC 파티션에서 커널, dtb 그리고 RFS를 로드하는 자세한 방법은 uboot 브링업 섹션을 참조한다.
Debugging (디버깅)
일반적으로 우리는 uBoot와 커널 디버그 콘솔에 익숙하다. 그러나 BOOTROM과 연결된 저수준의 소프트웨어 컴포넌트를 사용하면 디버깅이 어려울 수 있다. NXP i.MX8
플랫폼에는 SCFW 디버깅을 위해 구성하고 사용할 수 있는 전용 UART가 있다. 이 UART를 SCFW에만 사용해야 하는 경우, 해당 SoC 패드가 SCFW에서 고정으로 구성되었는지 확인해야 한다. 또한, 하드웨어 디자인에서 애플리케이션 코어가 동일한 패드를 다른 용도로 사용하지 않도록 해야 한다.
애플리케이션 코어에 여러 UART를 사용할 수 있다. 이들 중 하나는 하드웨어 디자인에서 시리얼 콘솔로 구성할 수 있으며, 시리얼 디버깅 목적으로 사용할 수 있다.
커널에서 대부분의 문제를 디버깅하려면 항상 bootargs에서 디버그 옵션을 활성화해야 한다. 이렇게 하면, 시리얼 콘솔에 대한 추가 디버깅 정보가 활성화되어 도움이 될 수 있다.
Conclusion (결론)
i.MX8 제품군은 이전 i.MX SOC 버전과 비교할 때 부팅 절차가 다르다. 이 문서에서는 사용자 정의 보드에 필요한 하드웨어와 소프트웨어 세부 정보를 제공했다. 또한 개발 중에 직면한 다양한 디버깅 기술, 사용자 정의와 기술적 문제에 대해서도 다루었다. 이 문서가 i.MX8 아키텍처를 사용하여 애플리케이션을 구축하는 데 도움이 되기를 바란다.