삽입식 uboot에서 tftp 코드 추적

4133 단어
1. 네트워크 카드 구동의 추가
네트워크가 uboot에서 시작되는 것은 uboot의 두 번째 단계 시작 코드에서/libarm/board.c
<span style="font-family:Courier New;font-size:12px;">void start_armboot (void){}</span>

네트워크 초기화 함수가 들어있어요.
<span style="font-family:Courier New;font-size:12px;">eth_initialize(gd->bd);</span>

함수에 들어가면 일련의 네트워크 카드 초기화 함수를 발견할 수 있다
<span style="font-family:Courier New;font-size:12px;">#if defined(CONFIG_MCFFEC)
	mcffec_initialize(bis);
#endif
#if defined(CONFIG_FSLDMAFEC)
	mcdmafec_initialize(bis);
#endif
#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
    defined(CONFIG_AT91SAM9263)
	at91sam9_eth_initialize(bis);
#endif

#if defined(CONFIG_DRIVER_CS8900)
	cs8900_initialize(bis);
#endif

#if defined(CONFIG_DRIVER_SMC911X)
	smc911x_initialize(bis);
#endif</span>

나는 smc9220의 인터넷 카드이기 때문에 찾았다
<span style="font-family:Courier New;font-size:12px;">#if defined(CONFIG_DRIVER_SMC911X)
 smc911x_initialize(bis);
#endif</span>

그러면 이 카드를 추가하려면 앞에 매크로 CONFIG 를 정의해야 합니다.DRIVER_SMC911X 
이 매크로는/configs/unsp210에 있습니다.h에서 정의하면 돼요.
계속 따라가기
smc911x_initialize(bis)는 모든 카드에 이런 함수가 있습니다. 서로 다른 카드를 설정하고 싶을 때 이 함수에 등록하면 됩니다. (사실 등록이 아니라 장치를 체인 테이블에 넣어서 관리하기 편합니다.)
smc911x_initialize 함수 중 관건은 여기에 있다
<span style="font-family:Courier New;font-size:12px;"> dev = (struct eth_device *) malloc (sizeof *dev);
 memcpy(dev->enetaddr, bis->bi_enetaddr, 6);
 sprintf(dev->name, DRIVERNAME); //   
 dev->priv = (void *)NULL; /* this have to come before bus_to_phys() */
 dev->iobase = CONFIG_DRIVER_SMC911X_BASE;
 dev->init = smc911x_eth_init;    //        
 dev->halt = smc911x_eth_halt;
 dev->send = smc911x_eth_send;     //         
 dev->recv = smc911x_eth_rx;    //         
 eth_register (dev); //               ,         </span>

eth_register () 함수에 이런 말이 있어요.
<span style="font-family:Courier New;font-size:12px;">eth_current = eth_devices = dev;</span>

이곳에 도착하면 eth 를 사용할 수 있습니다devices 및 ethcurrent가 통신했습니다. (구체적인 밑바닥 함수는 u-boot\driverset\디렉터리에서 해당하는.c 파일을 볼 수 있습니다. 여기는 더 이상 따라가지 않습니다.)
여기까지만 따라가면 네트워크 카드 드라이브가 어떻게 위와 연결되는지 알 수 있습니다. 그러면 TFTP 명령이 실행되는 과정을 살펴보겠습니다.
2. uboot에서 네트워크 명령의 실현 과정
그러면 UBOOT에서 가장 많이 사용하는 명령은 업데이트나 tftp가 네트워크를 통해 핵과 루트 파일 시스템을 다운로드하는 것입니다.
이 두 명령은 또 어떻게 네트워크를 호출합니까?
1. 먼저 tftp 명령이 uboot에서 이루어지는 과정
   common/cmd_net.c에 정의가 있다
<span style="font-family:Courier New;font-size:12px;">int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
 return netboot_common (TFTP, cmdtp, argc, argv);
}

U_BOOT_CMD(
 tftpboot,	3,	1,	do_tftpb,
 "tftpboot- boot image via network using TFTP protocol
", "[loadAddress] [[hostIPaddr:]bootfilename]
" );</span>

U_BOOT_CMD는 첫 번째 인자의 명령 tftpboot에 대응하는 함수 dotftpb()
Dotftpb ()에서 netbootcommon () 함수에서 NetLoop(proto)을 사용하여 tftp를 시작합니다.
NetLoop(proto t protocol) 함수는/net/net에 있습니다.c 중
아래에는 매개 변수 프로토콜 유형에 따라 상응하는 함수를 실행하고 위의 코드에서 TFTP가 전달되는 것을 볼 수 있기 때문에 TFTP 세그먼트 코드를 실행합니다
<span style="font-family:Courier New;font-size:12px;">switch (protocol) {
  case TFTP:
   /* always use ARP to get server ethernet address */
   TftpStart();
   break;
。。。
}</span>

다음은 TftpStart () 의 일입니다.
2. tftp 명령이 실행된 후 가장 먼저 실행되는 함수는/net/tftp.c의 TftpStart () 함수 중 관건은 두 군데인데 하나는 한 군데를 거두고 하나는 보내는 것이다
받다
NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
NetSetHandler (TftpHandler);
이 두 함수는 받는 문제를 해결했다. TftpHandler 함수는 데이터가 있을 때 자동으로 집행된다. 의심할 여지없이 TftpHandler 안에 수신 처리 함수가 있다.
마지막 TftpSend();
데이터를 보내는 것은 UDP를 사용하는 함수입니다. 따라가면 마지막에 사용한 원시 데이터를 발견할 수 있습니다. (자신이 실현한 UDP 헤더 IP 헤더 이더넷 헤더)
NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len);

좋은 웹페이지 즐겨찾기