리눅스 커널 부트 프로세스
uboot는 bootcmd 명령어를 통해 커널을 실행합니다:
bootcmd="nand read 0x30000000 kernel; bootm 0x30000000"
uboot는 NAND에서 커널 이미지를 0x30000000 메모리 주소로 복사한 후 bootm 명령을 실행합니다.
bootm 명령 처리
bootm은 운영체제 맵을 시작하는 함수로, arch/arm/lib/bootm.c의 do_bootm_linux 함수를 호출합니다:
int handle_boot_linux(int flags, int count, char * const args[],
boot_headers_t *img)
{
if (flags & BOOTM_STATE_OS_BD_T || flags & BOOTM_STATE_OS_CMDLINE)
return -1;
if (flags & BOOTM_STATE_OS_PREP) {
prepare_linux_boot(img);
return 0;
}
if (flags & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
jump_to_linux(img, flags);
return 0;
}
prepare_linux_boot(img);
jump_to_linux(img, flags);
return 0;
}
prepare_linux_boot는 부트 파라미터 설정을 담당하며, jump_to_linux는 태그 주소(gd->bd->bi_boot_params)를 커널에 전달합니다.
점프 메커니즘
static void jump_to_linux(boot_headers_t *img, int flags)
{
unsigned long machine_id = gd->bd->bi_arch_num;
void (*kernel_start)(int zero, int arch, uint params);
unsigned long param_addr;
int simulated = (flags & BOOTM_STATE_OS_FAKE_GO);
kernel_start = (void (*)(int, int, uint))img->entry;
if (IMAGE_ENABLE_OF_LIBFDT && img->fdt_length)
param_addr = (unsigned long)img->fdt_addr;
else
param_addr = gd->bd->bi_boot_params;
if (!simulated) {
kernel_start(0, machine_id, param_addr);
}
}
디바이스 트리 사용 시 param_addr은 dtb 시작 주소로 설정됩니다.
디바이스 트리 포팅
Linux 5.2.8 소스코드를 기반으로 Mini2440용 디바이스 트리를 구성합니다.
커널 설정
Makefile 수정:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
s3c2440_defconfig 생성:
cp arch/arm/configs/s3c2410_defconfig arch/arm/configs/s3c2440_defconfig
디바이스 트리 추가
DTS 파일 생성:
cp s3c2416.dtsi s3c2440.dtsi
cp s3c2416-pinctrl.dtsi s3c2440-pinctrl.dtsi
cp s3c2416-smdk2416.dts s3c2440-smdk2440.dts
Makefile에 타겟 추가:
dtb-$(CONFIG_ARCH_S3C24XX) += s3c2440-smdk2440.dtb
하드웨어 지원 설정
Kconfig에 ARCH_S3C2440_DT 옵션 추가:
config ARCH_S3C2440_DT
bool "MINI2440 with devicetree"
select TIMER_OF
select USE_OF
select PINCTRL
select PINCTRL_S3C24XX
매칭 머신 파일 생성 (mach-smdk2440-dt.c):
static const char *const s3c2440_dt_compat[] __initconst = {
"samsung,s3c2440",
"samsung,mini2440",
NULL
};
DT_MACHINE_START(S3C2440_DT, "Samsung S3C2440 (Flattened Device Tree)")
.dt_compat = s3c2440_dt_compat,
...
커널 최적화
menuconfig 설정:
Boot options → Flattened Device Tree support
Device Drivers → Network → Ethernet → DM9000 support
File systems → Network File Systems → NFS client
Kernel hacking → Early printk
Kernel Features → ARM EABI
U-Boot FDT 지원
uboot 설정 파일에 추가:
CONFIG_OF_LIBFDT=y
부트 명령:
tftp 0x30001000 s3c2440-smdk2440.dtb
tftp 0x30008000 uImage
bootm 0x30008000 - 0x30001000