Uboot에서 tftp 다운로드가 멈추는 문제

U-Boot에서 tftp 명령으로 커널 이미지나 rootfs를 받아오다가 진행률이 멈추거나, Loading: * 이후로 아무 반응 없이 프롬프트로 돌아와 버리는 경우가 있다. 케이블도 꽂혀 있고 서버도 떠 있는데 왜 멈추는지는 로그 한 줄만 봐서는 알기 어렵다. 이 글에서는 원인이 될 수 있는 지점들을 정리하고, QEMU로 성공/실패 케이스를 각각 실제로 재현해본다.

원인이 될 수 있는 지점들

원인증상
serverip/ipaddr가 실제 네트워크와 안 맞음“Loading:” 이후 ARP Retry count exceeded; starting again로 즉시 중단
스위치 STP로 인해 링크업 직후 포트가 forwarding 상태가 아님부팅 후 곧바로 tftp를 시작하면 수십 초간 패킷이 전부 드롭됨
PHY RGMII 클럭 지연 등 보드 하드웨어 신호 문제작은 파일은 되는데 큰 이미지 전송 중간에 멈추거나 깨짐
TFTP 서버가 windowsize/blocksize 확장을 지원하지 않음협상 단계에서 재시도를 반복하다 멈춤
타임아웃/재시도 횟수 기본값이 실제 왕복 지연보다 짧음느린 네트워크에서 정상 전송인데도 재시도 후 실패로 종료

QEMU로 실제 재현하기

mainline U-Boot를 qemu_arm64_defconfig로 빌드해 QEMU의 usermode 네트워크(내장 TFTP 서버, 게이트웨이 10.0.2.2)로 정상 전송부터 확인했다.

=> setenv ipaddr 10.0.2.15
=> setenv serverip 10.0.2.2
=> tftp 0x40200000 test.bin
Using virtio-net#31 device
TFTP from server 10.0.2.2; our IP address is 10.0.2.15
Filename 'test.bin'.
Load address: 0x40200000
Loading: *#####################################
	 6.2 MiB/s
done
Bytes transferred = 524288 (80000 hex)

이제 serverip만 존재하지 않는 주소(10.0.2.50)로 바꿔서, “서버는 있는데 응답이 없는” 흔한 상황을 재현했다.

=> setenv serverip 10.0.2.50
=> tftp 0x40200000 test.bin
Using virtio-net#31 device
TFTP from server 10.0.2.50; our IP address is 10.0.2.15
Filename 'test.bin'.
Load address: 0x40200000
Loading: *
ARP Retry count exceeded; starting again

이 메시지는 U-Boot 소스의 net/arp.c에 그대로 있다.

if (arp_wait_try >= CONFIG_NET_RETRY_COUNT) {
	puts("\nARP Retry count exceeded; starting again\n");
	...
}

즉 tftp 자체가 아니라 그 앞 단계인 ARP 응답을 CONFIG_NET_RETRY_COUNT번 재시도할 때까지 못 받은 것이다. 실제 환경에서는 잘못된 serverip/게이트웨이 설정, 혹은 스위치가 그 시점에 ARP 브로드캐스트를 포워딩하지 않는 상태(STP 등)일 때 이 메시지가 나온다.

tftp 전에 ping으로 먼저 경로를 확인하면 ARP 문제인지 아닌지를 빠르게 구분할 수 있다.

=> ping 10.0.2.2
Using virtio-net#31 device
host 10.0.2.2 is alive

타임아웃/재시도 관련 환경변수

net/tftp.ctftp_start()는 아래 환경변수를 읽어 타임아웃과 블록/윈도 크기를 조정한다(CONFIG_NET_TFTP_VARS 활성화 시).

환경변수역할
tftpblocksizeTFTP 블록 크기(옥텟 옵션) 협상값 지정
tftpwindowsizeACK 없이 연속으로 보낼 블록 수(RFC 7440 windowsize) 지정
tftptimeout블록 하나에 대한 타임아웃(ms), 최소 1000
tftptimeoutcountmax타임아웃 재시도 최대 횟수

서버가 windowsize 확장을 지원하지 않아 재협상을 반복한다면 setenv tftpwindowsize 1로 꺼보고, 네트워크 자체가 느려 정상 전송인데도 끊긴다면 tftptimeout/tftptimeoutcountmax를 늘려서 구분한다.

주의사항

  • 관리형 스위치를 쓴다면 보드가 물린 포트에 portfast(edge port) 설정이 있는지 확인할 것 — STP forwarding delay 때문에 링크업 직후 몇십 초간 부팅 스크립트가 실패하는 경우가 흔하다.
  • 같은 케이블/포트에서 작은 파일은 되는데 큰 이미지에서만 멈춘다면 소프트웨어보다 PHY/RGMII 배선 쪽(보드 디바이스 트리의 클럭 지연 설정 등) 하드웨어 원인을 의심할 것 — 이 부분은 QEMU 가상 NIC로는 재현이 안 돼 이 글에서 직접 검증하지 못했다.
  • tftptimeoutcountmax를 무작정 늘리기 전에 ping으로 경로가 살아있는지부터 확인할 것 — 경로 자체가 끊겨 있으면 재시도 횟수를 늘려도 결국 실패한다.

마무리

tftp가 멈추는 지점이 “Loading:” 직후인지, 진행 중간인지에 따라 원인 성격이 다르다. ARP 단계에서 막힌다면 IP/게이트웨이나 스위치 설정을, 전송 도중 멈춘다면 서버의 확장 옵션 지원 여부나 하드웨어 신호 문제를 먼저 의심하면 된다.

참고

답글 남기기