diff --git a/litex/soc/software/bios/boot.c b/litex/soc/software/bios/boot.c index ed7d3cbaf..3972f3b1f 100644 --- a/litex/soc/software/bios/boot.c +++ b/litex/soc/software/bios/boot.c @@ -210,11 +210,16 @@ int serialboot(void) #define REMOTEIP4 100 #endif -static int tftp_get_v(unsigned int ip, const char *filename, char *buffer) +#ifndef TFTP_SERVER_PORT +#define TFTP_SERVER_PORT 69 /* IANA well known port: UDP/69 */ +#endif + +static int tftp_get_v(unsigned int ip, unsigned short server_port, + const char *filename, char *buffer) { int r; - r = tftp_get(ip, filename, buffer); + r = tftp_get(ip, server_port, filename, buffer); if(r > 0) printf("Successfully downloaded %d bytes from %s over TFTP\n", r, filename); else @@ -229,6 +234,7 @@ void netboot(void) int size; unsigned int cmdline_adr, initrdstart_adr, initrdend_adr; unsigned int ip; + unsigned short tftp_port; printf("Booting from network...\n"); printf("Local IP : %d.%d.%d.%d\n", LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4); @@ -238,13 +244,17 @@ void netboot(void) microudp_start(macadr, IPTOINT(LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4)); - if(tftp_get_v(ip, "boot.bin", (void *)MAIN_RAM_BASE) <= 0) { + tftp_port = TFTP_SERVER_PORT; + printf("Fetching from: UDP/%d\n", tftp_port); + + if(tftp_get_v(ip, tftp_port, "boot.bin", (void *)MAIN_RAM_BASE) <= 0) { + /* XXX: Try alternate TFTP port here? */ printf("Network boot failed\n"); return; } cmdline_adr = MAIN_RAM_BASE+0x1000000; - size = tftp_get_v(ip, "cmdline.txt", (void *)cmdline_adr); + size = tftp_get_v(ip, tftp_port, "cmdline.txt", (void *)cmdline_adr); if(size <= 0) { printf("No command line parameters found\n"); cmdline_adr = 0; @@ -252,7 +262,7 @@ void netboot(void) *((char *)(cmdline_adr+size)) = 0x00; initrdstart_adr = MAIN_RAM_BASE+0x1002000; - size = tftp_get_v(ip, "initrd.bin", (void *)initrdstart_adr); + size = tftp_get_v(ip, tftp_port, "initrd.bin", (void *)initrdstart_adr); if(size <= 0) { printf("No initial ramdisk found\n"); initrdstart_adr = 0; diff --git a/litex/soc/software/include/net/tftp.h b/litex/soc/software/include/net/tftp.h index 7babb2d77..788731ba0 100644 --- a/litex/soc/software/include/net/tftp.h +++ b/litex/soc/software/include/net/tftp.h @@ -3,8 +3,10 @@ #include -int tftp_get(uint32_t ip, const char *filename, void *buffer); -int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size); +int tftp_get(uint32_t ip, uint16_t server_port, const char *filename, + void *buffer); +int tftp_put(uint32_t ip, uint16_t server_port, const char *filename, + const void *buffer, int size); #endif /* __TFTP_H */ diff --git a/litex/soc/software/libnet/tftp.c b/litex/soc/software/libnet/tftp.c index 8a9ecf219..3cbcec3a4 100644 --- a/litex/soc/software/libnet/tftp.c +++ b/litex/soc/software/libnet/tftp.c @@ -4,7 +4,7 @@ #include #include -#define PORT_OUT 69 +/* Local TFTP client port (arbitrary) */ #define PORT_IN 7642 enum { @@ -100,7 +100,8 @@ static void rx_callback(uint32_t src_ip, uint16_t src_port, } } -int tftp_get(uint32_t ip, const char *filename, void *buffer) +int tftp_get(uint32_t ip, uint16_t server_port, const char *filename, + void *buffer) { int len; int tries; @@ -120,7 +121,7 @@ int tftp_get(uint32_t ip, const char *filename, void *buffer) while(1) { packet_data = microudp_get_tx_buffer(); len = format_request(packet_data, TFTP_RRQ, filename); - microudp_send(PORT_IN, PORT_OUT, len); + microudp_send(PORT_IN, server_port, len); for(i=0;i<2000000;i++) { microudp_service(); if((total_length > 0) || transfer_finished) break; @@ -152,7 +153,8 @@ int tftp_get(uint32_t ip, const char *filename, void *buffer) return total_length; } -int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size) +int tftp_put(uint32_t ip, uint16_t server_port, const char *filename, + const void *buffer, int size) { int len, send; int tries; @@ -172,7 +174,7 @@ int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size) while(1) { packet_data = microudp_get_tx_buffer(); len = format_request(packet_data, TFTP_WRQ, filename); - microudp_send(PORT_IN, PORT_OUT, len); + microudp_send(PORT_IN, server_port, len); for(i=0;i<2000000;i++) { last_ack = -1; microudp_service();