5.1. 32-bit soft-float ARM에서 설치 프로그램 부팅하기

5.1.1. 부팅 이미지 형식

ARM 시스템에서는 대부분의 경우 1가지나 2가지의 부팅 이미지 형식을 사용합니다. (1) 표준 리눅스 zImage 형식의 커널 (vmlinuz) 및 표준 리눅스 초기 램디스크(initrd.gz), (2) uImage 형식의 커널 (uImage) 및 거기 해당하는 최초 램디스크(uInitrd).

uImage/uInitrd는 U-Boot 펌웨어에서 사용하려고 만들어진 이미지 형식입니다. u-boot는 여러 ARM 시스템에서(주로 32비트 시스템) 사용합니다. 예전 버전의 U-Boot에서는 uImage/uInitrd 형식의 파일만 부팅할 수 있습니다. 즉 이 형식은 예전의 armel 시스템에서 주로 사용합니다. 최근 버전의 U-Boot에서는 uImage/uInitrd 부팅 말고 표준 리눅스 커널과 램디스크 이미지로 부팅할 수 있습니다. 하지만 uImage 부팅과는 명령어 문법이 약간 다릅니다.

멀티 플랫폼 커널을 사용하는 시스템에서는, 커널과 최초 램디스크 외에 디바이스-트리 파일(device-tree blob, DTB라고도 합니다)이 필요합니다. 이 파일은 지원하는 시스템마다 다르고, 특정 하드웨어에 대한 설정이 들어 있습니다. DTB는 시스템의 펌웨어에서 만들어 내지만, 최근 시스템에서는 보통 따로 읽어들여야 합니다.

5.1.2. TFTP로 부팅하기

네트워크에서 부팅하려면, 네트워크에 연결되어 있어야 하고 TFTP 네트워크 부팅 서버가(그리고 네트워크 자동 설정에 필요한 DHCP, RARP 혹은 BOOTP 서버가) 필요합니다.

서버 쪽에서 네트워크 부팅을 설정하는 방법은 4.3절. “TFTP 네트워크 부팅에 필요한 파일 준비하기”에 설명되어 있습니다.

5.1.2.1. U-Boot에서 TFTP 부팅

U-Boot 펌웨어를 사용하는 시스템에서 네트워크 부팅은 3가지 단계로 이루어져 있습니다: (1) 네트워크 설정, (2) 이미지(커널/최초 램디스크/DTB) 메모리에 읽어들이기, (3) 읽어들인 코드 실행.

먼저 네트워크를 설정해야 합니다. 다음을 실행해 DHCP로 자동 설정할 수 있습니다:

setenv autoload no
dhcp

아니면 수동으로 환경 변수를 설정할 수 있습니다:

setenv ipaddr <클라이언트의 IP 주소>
setenv netmask <네트마스크>
setenv serverip <TFTP 서버의 IP 주소>
setenv dnsip <네임서버의 IP 주소>
setenv gatewayip <기본 게이트웨이의 IP 주소>

위 설정을 저장하고 싶으면 다음과 같이 합니다:

saveenv

그 다음에 이미지(커널/최초 램디스크/DTB)를 메모리에 읽어들여야 합니다. TFTP 명령에 메모리를 읽어들일 위치의 주소를 써야 합니다. 하지만 메모리 배치가 시스템마다 다르기 때문에 어떤 주소를 사용해야 하는지는 일반적인 규칙은 없습니다.

일부 시스템에서는, U-Boot에 적합한 로딩 주소가 환경 변수로 미리 정의되어 있습니다: kernel_addr_r, ramdisk_addr_r 및 fdt_addr_r. 이 환경 변수가 정의되어 있는지 여부를 다음 명령으로 확인해 볼 수 있습니다

printenv kernel_addr_r ramdisk_addr_r fdt_addr_r

이 값이 정의되어 있지 않으면, 시스템의 문서에서 적절한 값을 확인해 보고 직접 값으 지정해야 합니다. 예를 들어 Allwinner SunXi SOC 기반 시스템(예: Allwinner A10, 아키텍쳐 이름 sun4i 또는 Allwinner A20, 아키텍쳐 이름 sun7i)의 경우, 다음 값을 사용합니다.

setenv kernel_addr_r 0x46000000
setenv fdt_addr_r 0x47000000
setenv ramdisk_addr_r 0x48000000

로딩 주소를 지정하면, 다음과 같이 앞에서 지정한 TFTP 서버에서 이미지를 메모리에 읽어들일 수 있습니다:

tftpboot ${kernel_addr_r} <커널 이미지 파일 이름>
tftpboot ${fdt_addr_r} <DTB 파일 이름>
tftpboot ${ramdisk_addr_r} <최초 램디스크 이미지 파일 이름>

3번째는 커널 커맨드라인을 설정하고 읽어들인 코드를 실행하는 부분입니다. u-boot는 bootargs 환경 변수의 내용을 커널의 커맨드라인으로 넘깁니다. 그러므로 커널 및 설치 프로그램의 파라미터는(콘솔 장치(5.3.1절. “부팅 콘솔” 참고) 또는 미리 설정 옵션(5.3.2절. “데비안 설치프로그램 파라미터”부록 B. 미리 설정을 이용한 설치 자동화 참고)) 다음과 같은 명령으로 설정할 수 있습니다:

setenv bootargs console=ttyS0,115200 rootwait panic=10

읽어들인 코드를 실행하는 정확한 명령은 이미지 형식에 따라 다릅니다. uImage/uInitrd의 경우 명령어는 다음과 같고,

bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

네이티브 리눅스 이미지의 경우 다음과 같습니다:

bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}

표준 리눅스 이미지로 부팅할 때, 커널과 DTB를 읽어들이고 다음에 최초 램디스크 이미지를 읽어들이는 게 중요합니다. U-Boot에서는 파일 크기 변수를 마지막에 읽어들인 파일의 크기로 설정하고, bootz 명령이 제대로 동작하려면 램디스크 이미지의 크기가 필요하기 떄문입니다. 플랫폼 전용 커널로 부팅하는 경우(예를 들어 디바이스 트리 없는 커널)에는 ${fdt_addr_r} 파라미터를 생략하면 됩니다.

5.1.3. U-Boot 이용해 USB 메모리에서 부팅하기

최근의 U-Boot 버전에서는 USB를 지원하므로, USB 메모리와 같은 USB 대용량 저장소 장치에서 부팅할 수 있습니다. 아쉽지만 부팅하는 정확한 단계는 하드웨어마다 조금씩 다를 수 있습니다.

U-Boot v2014.10 버전부터 공통된 명령행 처리와 자동 부팅 프레임워크가 갖춰졌습니다. 이 기능 때문에 이 프레임워크를 구현한 시스템이라면 어디든 동작하는 일반적인 부팅 이미지를 만들 수 있게 되었습니다. debian-installer에서는 USB 메모리를 이용해 그러한 시스템을 부팅할 수 있습니다. 하지만 이 프레임워크를 아직 사용하지 않는 플랫폼도 있습니다.

데비안 설치에 사용할 부팅 가능 USB 메모리를 만드려면, hd-media 묶음을 (4.2.1절. “설치 이미지를 찾을 위치” 참고) USB 메모리에 풀어 놓습니다. USB 메모리는 하드웨어의 U-Boot 버전에서 지원하는 파일 시스템으로 포맷해야 합니다. 최근의 U-Boot 버전에서는 FAT16 / FAT32 / ext2 / ext3 / ext4 모두 동작합니다. 그리고 첫번째 데비안 설치 CD 또는 DVD의 ISO 이미지를 그 USB 메모리에 복사합니다.

최근 U-Boot 버전의 자동 부팅 프레임워크는 PC BIOS의 부팅 순서와 비슷하게 동작합니다. 즉 가능한 부팅 장치에서 부팅 이미지를 확인하고, 찾은 부팅 장치 중에서 첫 번째에서 부팅합니다. 운영 체제를 설치하지 않았으면, USB 메모리를 연결하고 전원을 켜면 설치 프로그램을 시작하게 됩니다. U-Boot 프롬프트에서 run usb_boot 명령을 입력하면 언제든지 USB 부팅을 할 수 있습니다.

시리얼 콘솔을 사용할 때 USB 메모리에서 부팅할 경우 발생할 수 있는 한 가지 문제는 보우레이트가 일치하지 않는 경우입니다. 콘솔 변수를 U-Boot에서 지정한 경우, debian-installer 부팅 스크립트에서 자동으로 커널에 전달해서 사용하는 콘솔 장치와 보우레이트를 설정합니다. 아쉽지만 콘솔 변수 처리는 플랫폼마다 다릅니다. 일부 시스템에서는 콘솔 변수에서 보우레이트를 지정하고 (console=ttyS0,115200처럼), 어떤 플랫폼에서는 콘솔 변수에 시리얼 장치만 (console=ttyS0처럼) 설정합니다. 후자의 경우 U-Boot와 커널이 사용하는 기본 보우레이트가 다른 경우 콘솔 출력이 깨질 수 있습니다. 최근의 u-boot 버전에서는 115200 보우레이트를 사용하지만, 여전히 커널은 전통적인 9600 보우레이트를 사용합니다. 이런 상황이 벌어지는 경우, 콘솔 변수를 수동으로 설정해서 시스템의 보우레이트를 바로잡고 run usb_boot 명령으로 설치 프로그램을 시작해야 합니다.