2025. 3. 6. 19:41ㆍ프로그래밍/시스템
3.2 새로운 SoC 지원을 위한 포팅
리눅스 커널은 다양한 SoC(System on Chip)를 지원하도록 설계되어 있습니다. 하지만 새로운 SoC를 지원하려면 SoC에 맞는 코드 추가 및 설정 변경이 필요합니다.
이 과정에서는 SoC의 초기화 코드, 디바이스 트리(DTS), Kconfig 및 Makefile 수정 방법을 다룹니다.
🔹 arch/arm/mach-* 디렉토리 분석 (SoC 지원 구조 이해)
리눅스 커널에서 ARM 기반 SoC를 지원하는 코드는 arch/arm/mach-* 디렉토리에 위치합니다.
✅ SoC 관련 디렉토리 구조 (arch/arm/mach-*)
linux/arch/arm/
├── boot/
│ ├── dts/ # 디바이스 트리 (Device Tree)
│ ├── compressed/ # 커널 압축 관련 코드
├── mach-at91/ # Atmel AT91 SoC 지원 코드
├── mach-exynos/ # 삼성 Exynos SoC 지원 코드
├── mach-omap2/ # TI OMAP2+ SoC 지원 코드
├── mach-rockchip/ # Rockchip SoC 지원 코드
├── mach-imx/ # NXP i.MX SoC 지원 코드
├── mach-sunxi/ # Allwinner SoC 지원 코드
└── mach-새로운 SoC/ # 새로운 SoC 추가
✅ SoC 지원을 위한 주요 파일
파일 | 역할 |
mach-*/Makefile | SoC 관련 코드 빌드 설정 |
mach-*/Kconfig | SoC 관련 커널 옵션 설정 |
mach-*/board-*.c | 특정 보드의 초기화 코드 |
mach-*/devices.c | SoC 내장 디바이스 등록 |
mach-*/system.c | SoC의 클럭 및 전원 관리 코드 |
🔹 특정 SoC 지원 코드 추가 (arch/arm/boot/dts/)
리눅스 커널에서 새로운 SoC를 지원하려면 디바이스 트리(Device Tree, DT) 를 추가해야 합니다.
✅ 1️⃣ 새로운 SoC용 디바이스 트리 파일 생성
cd arch/arm/boot/dts/
touch my_soc.dts
✅ 2️⃣ 새로운 SoC의 기본 구조 작성 (my_soc.dts)
/dts-v1/;
#include "my_soc.dtsi"
/ {
compatible = "mycompany,my_soc";
model = "My Custom SoC Board";
memory {
reg = <0x80000000 0x40000000>; /* 1GB RAM */
};
chosen {
bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2";
};
uart0: serial@10000000 {
compatible = "mycompany,my_soc-uart";
reg = <0x10000000 0x100>;
clock-frequency = <50000000>;
};
gpio: gpio@20000000 {
compatible = "mycompany,my_soc-gpio";
reg = <0x20000000 0x1000>;
};
};
- compatible → SoC와 보드 이름 정의
- memory → RAM 주소 및 크기 설정
- chosen → 부팅 시 커널 명령어 설정 (bootargs)
- uart0 → UART 시리얼 포트 설정
- gpio → GPIO 컨트롤러 설정
✅ 3️⃣ 공통 SoC 정보(my_soc.dtsi)
/dts-v1/;
/ {
cpus {
cpu@0 {
compatible = "arm,cortex-a53";
reg = <0>;
};
};
timer {
compatible = "arm,armv7-timer";
};
gic: interrupt-controller@1f000000 {
compatible = "arm,gic-400";
reg = <0x1f000000 0x1000>;
};
};
- cpus → CPU 코어 정의
- timer → ARM 타이머 설정
- gic → 인터럽트 컨트롤러 설정
✅ 4️⃣ 새로운 SoC를 Kconfig 및 Makefile에 추가 새로운 SoC를 커널에서 인식하도록 설정해야 합니다.
🔹 Kconfig 및 Makefile 수정하여 SoC 지원 추가
✅ 1️⃣ arch/arm/Kconfig 수정
vim arch/arm/Kconfig
config ARCH_MY_SOC
bool "Support for My Custom SoC"
select ARCH_GENERIC
help
This enables support for My Custom SoC.
- config ARCH_MY_SOC → 새로운 SoC 설정 추가
- select ARCH_GENERIC → 일반적인 ARM 커널 기능 사용
✅ 2️⃣ arch/arm/Makefile 수정
vim arch/arm/Makefile
ifeq ($(CONFIG_ARCH_MY_SOC),y)
machine-$(CONFIG_ARCH_MY_SOC) += my_soc
endif
- CONFIG_ARCH_MY_SOC 옵션이 활성화되면 my_soc 디렉토리 포함
✅ 3️⃣ arch/arm/mach-my_soc/Makefile 생성
cd arch/arm/
mkdir mach-my_soc
touch mach-my_soc/Makefile
obj-y += devices.o
obj-y += board.o
obj-y += system.o
- SoC 초기화 파일을 빌드하도록 설정
✅ 4️⃣ arch/arm/mach-my_soc/Kconfig 생성
vim arch/arm/mach-my_soc/Kconfig
menuconfig ARCH_MY_SOC
bool "Support for My Custom SoC"
select ARCH_GENERIC
✅ 5️⃣ arch/arm/mach-my_soc/board.c 생성
vim arch/arm/mach-my_soc/board.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/of.h>
static void __init my_soc_board_init(void)
{
pr_info("Initializing My Custom SoC\n");
}
arch_initcall(my_soc_board_init);
- arch_initcall()을 사용하여 SoC 초기화 코드 실행
✅ 6️⃣ arch/arm/mach-my_soc/devices.c 생성
vim arch/arm/mach-my_soc/devices.c
#include <linux/init.h>
#include <linux/platform_device.h>
static struct platform_device my_uart_device = {
.name = "my_soc-uart",
.id = -1,
};
static int __init my_soc_init_devices(void)
{
platform_device_register(&my_uart_device);
return 0;
}
arch_initcall(my_soc_init_devices);
- UART 디바이스를 등록하는 코드
✅ 7️⃣ 디바이스 트리 빌드
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dtbs
✅ 8️⃣ 새로운 SoC 커널 빌드
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- zImage -j$(nproc)
✅ 9️⃣ 부트로더에서 커널 실행
tftpboot 0x80000000 zImage
tftpboot 0x82000000 my_soc.dtb
bootz 0x80000000 - 0x82000000
✅ 정리
- SoC 지원을 위한 코드 분석
- arch/arm/mach-*에서 SoC별 초기화 코드 확인
- 디바이스 트리(arch/arm/boot/dts/) 추가
- SoC 지원 코드 추가
- my_soc.dts 및 my_soc.dtsi 파일 생성
- Kconfig 및 Makefile 수정하여 SoC 등록
- mach-my_soc/ 디렉토리에서 초기화 코드 작성
- 빌드 및 실행
- make dtbs로 디바이스 트리 빌드
- make zImage로 커널 빌드
- bootz 명령어로 SoC 기반 커널 실행
'프로그래밍 > 시스템' 카테고리의 다른 글
커널 포팅 (4. 드라이버 포팅 / 4.1 기본적인 디바이스 드라이버 개념) (0) | 2025.03.06 |
---|---|
커널 포팅 (3. 커널 포팅 기본 실습 / 3.3 부트 로그 분석 및 디버깅) (0) | 2025.03.06 |
커널 포팅 (3. 커널 포팅 기본 실습 / 3.1 타겟 보드 선택 및 디바이스 트리 설정) (0) | 2025.03.06 |
커널 포팅 (2. 커널 소스 분석 및 빌드 / 2.4 U-Boot과의 연동) (0) | 2025.03.06 |
커널 포팅 (2. 커널 소스 분석 및 빌드 / 2.3 크로스 컴파일러를 이용한 커널 빌드) (0) | 2025.03.06 |