Commit 76764638cd774ce8679b71c9843b9b13847d716e

Authored by tim
Committed by Phil Elwell
1 parent 5030f162

Update rpiboot for CM4 and rationlise -d behaviour.

* Add 2711 bootcode and FW binaries with the 4 suffix.
* Use the device descriptor to select the correct bootcode and
  hack it so that bootcode.bin translates to bootcode4.bin on a
  Pi4 allowing the files to remain in the same directory.
* Add the latest best for recovery.bin and pieeprom.bin for CM4
* Update the installer.

Move the second stage preparation until after the device descriptor
has been retrieved because BCM2711 needs a different bootcode.bin.

If the '-d' argument specified then check for bootcode.bin in the
specified directory and don't fail over to the embedded fmem files.

Remove the default 'msd' directory and the references to /usr/share
because the behaviour conflicts with the original change to use
the fmem files.
Makefile
1 -rpiboot: main.c msd/bootcode.h msd/start.h 1 +rpiboot: main.c msd/bootcode.h msd/start.h msd/bootcode4.h msd/start4.h
2 $(CC) -Wall -Wextra -g -o $@ $< -lusb-1.0 2 $(CC) -Wall -Wextra -g -o $@ $< -lusb-1.0
3 3
4 %.h: %.bin ./bin2c 4 %.h: %.bin ./bin2c
@@ -13,11 +13,13 @@ bin2c: bin2c.c @@ -13,11 +13,13 @@ bin2c: bin2c.c
13 uninstall: 13 uninstall:
14 rm -f /usr/bin/rpiboot 14 rm -f /usr/bin/rpiboot
15 rm -f /usr/share/rpiboot/usbbootcode.bin 15 rm -f /usr/share/rpiboot/usbbootcode.bin
  16 + rm -f /usr/share/rpiboot/usbbootcode4.bin
16 rm -f /usr/share/rpiboot/msd.elf 17 rm -f /usr/share/rpiboot/msd.elf
  18 + rm -f /usr/share/rpiboot/msd4.elf
17 rm -f /usr/share/rpiboot/buildroot.elf 19 rm -f /usr/share/rpiboot/buildroot.elf
18 rmdir --ignore-fail-on-non-empty /usr/share/rpiboot/ 20 rmdir --ignore-fail-on-non-empty /usr/share/rpiboot/
19 21
20 -clean: 22 +clean:
21 rm -f rpiboot msd/*.h bin2c 23 rm -f rpiboot msd/*.h bin2c
22 24
23 .PHONY: uninstall clean 25 .PHONY: uninstall clean
Readme.md
1 # USB boot code 1 # USB boot code
2 2
3 This is the USB MSD boot code which should work on the Raspberry Pi model A, Compute Module, Compute 3 This is the USB MSD boot code which should work on the Raspberry Pi model A, Compute Module, Compute
4 -module 3 and Raspberry Pi Zero. 4 +Module 3, Compute Module 4 and Raspberry Pi Zero.
5 5
6 This version of rpiboot has been modified to work from directories which contain the booting 6 This version of rpiboot has been modified to work from directories which contain the booting
7 -firmware. There is a default directory msd/ which contains bootcode.bin and start.elf to turn  
8 -the Raspberry Pi device into a USB Mass Storage Device (MSD). 7 +firmware. There is a msd/ directory which contains bootcode.bin and start.elf to turn
  8 +the Raspberry Pi device into a USB Mass Storage Device (MSD). If run without arguments
  9 +embedded versions of bootcode.bin and start.elf are used to enable the MSD behaviour.
  10 +
  11 +For more information run 'rpiboot -h'
  12 +
  13 +## Compute Module 4
  14 +On Compute Module 4 the EMMC disable jumper (GPIO 40) must be fitted to switch
  15 +the ROM to usbboot mode. Otherwise, the SPI EEPROM bootloader image will be loaded
  16 +instead.
9 17
10 ## Building 18 ## Building
11 19
debian/99-rpiboot.rules
1 -ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0a5c", ATTR{idProduct}=="276[34]", GROUP="plugdev" 1 +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0a5c", ATTR{idProduct}=="27[16][134]", GROUP="plugdev"
debian/control
@@ -11,4 +11,4 @@ Architecture: any @@ -11,4 +11,4 @@ Architecture: any
11 Depends: ${shlibs:Depends}, ${misc:Depends} 11 Depends: ${shlibs:Depends}, ${misc:Depends}
12 Description: Raspberry Pi USB booting code 12 Description: Raspberry Pi USB booting code
13 USB MSD boot code which should work on the Raspberry Pi model A, 13 USB MSD boot code which should work on the Raspberry Pi model A,
14 - Compute Module, Compute module 3 and Raspberry Pi Zero. 14 + Compute Module, Compute Module 3, Compute Module 4 and Raspberry Pi Zero.
debian/rpiboot.install
1 rpiboot usr/bin 1 rpiboot usr/bin
2 msd/*.elf usr/share/rpiboot/msd/ 2 msd/*.elf usr/share/rpiboot/msd/
3 msd/*.bin usr/share/rpiboot/msd/ 3 msd/*.bin usr/share/rpiboot/msd/
  4 +recovery/*.bin usr/share/rpiboot/recovery/
  5 +recovery/*.sig usr/share/rpiboot/recovery/
  6 +recovery/*.txt usr/share/rpiboot/recovery/
4 debian/99-rpiboot.rules /lib/udev/rules.d 7 debian/99-rpiboot.rules /lib/udev/rules.d
debian/rpiboot.lintian-overrides
@@ -3,3 +3,7 @@ rpiboot: arch-dependent-file-in-usr-share usr/share/rpiboot/msd/start.elf @@ -3,3 +3,7 @@ rpiboot: arch-dependent-file-in-usr-share usr/share/rpiboot/msd/start.elf
3 rpiboot: binary-from-other-architecture usr/share/rpiboot/msd/start.elf 3 rpiboot: binary-from-other-architecture usr/share/rpiboot/msd/start.elf
4 rpiboot: unstripped-binary-or-object usr/share/rpiboot/msd/start.elf 4 rpiboot: unstripped-binary-or-object usr/share/rpiboot/msd/start.elf
5 rpiboot: statically-linked-binary usr/share/rpiboot/msd/start.elf 5 rpiboot: statically-linked-binary usr/share/rpiboot/msd/start.elf
  6 +rpiboot: arch-dependent-file-in-usr-share usr/share/rpiboot/msd/start4.elf
  7 +rpiboot: binary-from-other-architecture usr/share/rpiboot/msd/start4.elf
  8 +rpiboot: unstripped-binary-or-object usr/share/rpiboot/msd/start4.elf
  9 +rpiboot: statically-linked-binary usr/share/rpiboot/msd/start4.elf
debian/rules
@@ -4,4 +4,4 @@ @@ -4,4 +4,4 @@
4 dh $@ 4 dh $@
5 5
6 override_dh_strip: 6 override_dh_strip:
7 - dh_strip -Xstart.elf 7 + dh_strip -Xstart.elf -Xstart4.elf
debian/source.lintian-overrides
1 rpiboot: source-is-missing msd/start.elf 1 rpiboot: source-is-missing msd/start.elf
  2 +rpiboot: source-is-missing msd/start4.elf
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 7
8 #include "msd/bootcode.h" 8 #include "msd/bootcode.h"
9 #include "msd/start.h" 9 #include "msd/start.h"
  10 +#include "msd/bootcode4.h"
  11 +#include "msd/start4.h"
10 12
11 /* Assume BSD without native fmemopen() if doesn't seem to be glibc */ 13 /* Assume BSD without native fmemopen() if doesn't seem to be glibc */
12 #if defined(__APPLE__) || (!defined(_GNU_SOURCE) && (!defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L)) 14 #if defined(__APPLE__) || (!defined(_GNU_SOURCE) && (!defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200809L))
@@ -24,6 +26,10 @@ uint8_t targetPortNo = 99; @@ -24,6 +26,10 @@ uint8_t targetPortNo = 99;
24 26
25 int out_ep; 27 int out_ep;
26 int in_ep; 28 int in_ep;
  29 +int bcm2711;
  30 +
  31 +static FILE * check_file(const char * dir, const char *fname, int use_fmem);
  32 +static int second_stage_prep(FILE *fp, FILE *fp_sig);
27 33
28 typedef struct MESSAGE_S { 34 typedef struct MESSAGE_S {
29 int length; 35 int length;
@@ -39,6 +45,10 @@ void usage(int error) @@ -39,6 +45,10 @@ void usage(int error)
39 fprintf(dest, "Boot a Raspberry Pi in device mode either directly into a mass storage device\n"); 45 fprintf(dest, "Boot a Raspberry Pi in device mode either directly into a mass storage device\n");
40 fprintf(dest, "or provide a set of boot files in a directory from which to boot. This can\n"); 46 fprintf(dest, "or provide a set of boot files in a directory from which to boot. This can\n");
41 fprintf(dest, "then contain a initramfs to boot through to linux kernel\n\n"); 47 fprintf(dest, "then contain a initramfs to boot through to linux kernel\n\n");
  48 + fprintf(dest, "To flash the default bootloader EEPROM image on Compute Module 4 run\n");
  49 + fprintf(dest, "rpiboot -d recovery\n\n");
  50 + fprintf(dest, "For more information about the bootloader EEPROM please see:\n");
  51 + fprintf(dest, "https://www.raspberrypi.org/documentation/hardware/raspberrypi/booteeprom.md\n\n");
42 fprintf(dest, "rpiboot : Boot the device into mass storage device\n"); 52 fprintf(dest, "rpiboot : Boot the device into mass storage device\n");
43 fprintf(dest, "rpiboot -d [directory] : Boot the device using the boot files in 'directory'\n"); 53 fprintf(dest, "rpiboot -d [directory] : Boot the device using the boot files in 'directory'\n");
44 fprintf(dest, "Further options:\n"); 54 fprintf(dest, "Further options:\n");
@@ -110,8 +120,47 @@ libusb_device_handle * LIBUSB_CALL open_device_with_vid( @@ -110,8 +120,47 @@ libusb_device_handle * LIBUSB_CALL open_device_with_vid(
110 desc.idProduct == 0x2764 || 120 desc.idProduct == 0x2764 ||
111 desc.idProduct == 0x2711) 121 desc.idProduct == 0x2711)
112 { 122 {
  123 + FILE *fp_second_stage = NULL;
  124 + FILE *fp_sign = NULL;
  125 + const char *second_stage;
  126 +
113 if(verbose == 2) 127 if(verbose == 2)
114 - printf("Found candidate Compute Module..."); 128 + printf("Found candidate Compute Module...");
  129 +
  130 + bcm2711 = (desc.idProduct == 0x2711);
  131 + if (bcm2711)
  132 + second_stage = "bootcode4.bin";
  133 + else
  134 + second_stage = "bootcode.bin";
  135 +
  136 + fp_second_stage = check_file(directory, second_stage, 1);
  137 + if (!fp_second_stage)
  138 + {
  139 + fprintf(stderr, "Failed to open %s\n", second_stage);
  140 + exit(1);
  141 + }
  142 +
  143 + if (signed_boot && !bcm2711) // Signed boot use a different mechanism on BCM2711
  144 + {
  145 + const char *sig_file = "bootcode.sig";
  146 + fp_sign = check_file(directory, sig_file, 1);
  147 + if (!fp_sign)
  148 + {
  149 + fprintf(stderr, "Unable to open '%s'\n", sig_file);
  150 + usage(1);
  151 + }
  152 + }
  153 +
  154 + if (second_stage_prep(fp_second_stage, fp_sign) != 0)
  155 + {
  156 + fprintf(stderr, "Failed to prepare the second stage bootcode\n");
  157 + exit(-1);
  158 + }
  159 + if (fp_second_stage)
  160 + fclose(fp_second_stage);
  161 +
  162 + if (fp_sign)
  163 + fclose(fp_sign);
115 164
116 /////////////////////////////////////////////////////////////////////// 165 ///////////////////////////////////////////////////////////////////////
117 // Check if we should match against a specific port number 166 // Check if we should match against a specific port number
@@ -350,6 +399,10 @@ int second_stage_prep(FILE *fp, FILE *fp_sig) @@ -350,6 +399,10 @@ int second_stage_prep(FILE *fp, FILE *fp_sig)
350 fread(boot_message.signature, 1, sizeof(boot_message.signature), fp_sig); 399 fread(boot_message.signature, 1, sizeof(boot_message.signature), fp_sig);
351 } 400 }
352 401
  402 + if (second_stage_txbuf)
  403 + free(second_stage_txbuf);
  404 + second_stage_txbuf = NULL;
  405 +
353 second_stage_txbuf = (uint8_t *) malloc(boot_message.length); 406 second_stage_txbuf = (uint8_t *) malloc(boot_message.length);
354 if (second_stage_txbuf == NULL) 407 if (second_stage_txbuf == NULL)
355 { 408 {
@@ -403,7 +456,7 @@ int second_stage_boot(libusb_device_handle *usb_device) @@ -403,7 +456,7 @@ int second_stage_boot(libusb_device_handle *usb_device)
403 } 456 }
404 457
405 458
406 -FILE * check_file(char * dir, char *fname) 459 +FILE * check_file(const char * dir, const char *fname, int use_fmem)
407 { 460 {
408 FILE * fp = NULL; 461 FILE * fp = NULL;
409 char path[256]; 462 char path[256];
@@ -415,7 +468,6 @@ FILE * check_file(char * dir, char *fname) @@ -415,7 +468,6 @@ FILE * check_file(char * dir, char *fname)
415 return NULL; 468 return NULL;
416 } 469 }
417 470
418 - // Check directory first then /usr/share/rpiboot  
419 if(dir) 471 if(dir)
420 { 472 {
421 if(overlay&&(pathname[0] != 0)) 473 if(overlay&&(pathname[0] != 0))
@@ -438,13 +490,24 @@ FILE * check_file(char * dir, char *fname) @@ -438,13 +490,24 @@ FILE * check_file(char * dir, char *fname)
438 } 490 }
439 } 491 }
440 492
441 - if(fp == NULL) 493 + // Failover to fmem unless use_fmem is zero in which case this function
  494 + // is being used to check if a file exists.
  495 + if(fp == NULL && use_fmem)
442 { 496 {
443 - if(strcmp(fname, "bootcode.bin") == 0)  
444 - fp = fmemopen(msd_bootcode_bin, msd_bootcode_bin_len, "rb"); 497 + if (bcm2711)
  498 + {
  499 + if(strcmp(fname, "bootcode4.bin") == 0)
  500 + fp = fmemopen(msd_bootcode4_bin, msd_bootcode4_bin_len, "rb");
  501 + else if(strcmp(fname, "start4.elf") == 0)
  502 + fp = fmemopen(msd_start4_elf, msd_start4_elf_len, "rb");
  503 + }
445 else 504 else
446 - if(strcmp(fname, "start.elf") == 0) 505 + {
  506 + if(strcmp(fname, "bootcode.bin") == 0)
  507 + fp = fmemopen(msd_bootcode_bin, msd_bootcode_bin_len, "rb");
  508 + else if(strcmp(fname, "start.elf") == 0)
447 fp = fmemopen(msd_start_elf, msd_start_elf_len, "rb"); 509 fp = fmemopen(msd_start_elf, msd_start_elf_len, "rb");
  510 + }
448 } 511 }
449 512
450 return fp; 513 return fp;
@@ -485,7 +548,7 @@ int file_server(libusb_device_handle * usb_device) @@ -485,7 +548,7 @@ int file_server(libusb_device_handle * usb_device)
485 case 0: // Get file size 548 case 0: // Get file size
486 if(fp) 549 if(fp)
487 fclose(fp); 550 fclose(fp);
488 - fp = check_file(directory, message.fname); 551 + fp = check_file(directory, message.fname, 1);
489 if(strlen(message.fname) && fp != NULL) 552 if(strlen(message.fname) && fp != NULL)
490 { 553 {
491 int file_size; 554 int file_size;
@@ -571,8 +634,6 @@ int file_server(libusb_device_handle * usb_device) @@ -571,8 +634,6 @@ int file_server(libusb_device_handle * usb_device)
571 634
572 int main(int argc, char *argv[]) 635 int main(int argc, char *argv[])
573 { 636 {
574 - FILE * second_stage;  
575 - FILE * fp_sign = NULL;  
576 libusb_context *ctx; 637 libusb_context *ctx;
577 libusb_device_handle *usb_device; 638 libusb_device_handle *usb_device;
578 struct libusb_device_descriptor desc; 639 struct libusb_device_descriptor desc;
@@ -583,31 +644,37 @@ int main(int argc, char *argv[]) @@ -583,31 +644,37 @@ int main(int argc, char *argv[])
583 // flush immediately 644 // flush immediately
584 setbuf(stdout, NULL); 645 setbuf(stdout, NULL);
585 646
586 - // Default to standard msd directory  
587 - if(directory == NULL)  
588 - directory = "msd";  
589 -  
590 - second_stage = check_file(directory, "bootcode.bin");  
591 - if(second_stage == NULL) 647 + // If the boot directory is specified then check that it contains bootcode files.
  648 + if (directory)
592 { 649 {
593 - fprintf(stderr, "Unable to open 'bootcode.bin' from /usr/share/rpiboot/msd or supplied directory\n");  
594 - usage(1);  
595 - } 650 + FILE *f, *f4;
596 651
597 - if(signed_boot)  
598 - {  
599 - fp_sign = check_file(directory, "bootsig.bin");  
600 - if(fp_sign == NULL) 652 + if (verbose)
  653 + printf("Boot directory '%s'\n", directory);
  654 +
  655 + f = check_file(directory, "bootcode.bin", 0);
  656 + f4 = check_file(directory, "bootcode4.bin", 0);
  657 + if (!f && !f4)
601 { 658 {
602 - fprintf(stderr, "Unable to open 'bootsig.bin'\n"); 659 + fprintf(stderr, "No 'bootcode' files found in '%s'\n", directory);
603 usage(1); 660 usage(1);
604 } 661 }
605 - }  
606 662
607 - if(second_stage_prep(second_stage, fp_sign) != 0)  
608 - {  
609 - fprintf(stderr, "Failed to prepare the second stage bootcode\n");  
610 - exit(-1); 663 + if (f)
  664 + fclose(f);
  665 + if (f4)
  666 + fclose(f4);
  667 +
  668 + if (signed_boot)
  669 + {
  670 + f = check_file(directory, "bootsig.bin", 0);
  671 + if (!f)
  672 + {
  673 + fprintf(stderr, "Unable to open 'bootsig.bin' from %s\n", directory);
  674 + usage(1);
  675 + }
  676 + fclose(f);
  677 + }
611 } 678 }
612 679
613 int ret = libusb_init(&ctx); 680 int ret = libusb_init(&ctx);
msd/bootcode4.bin 0 → 100644
No preview for this file type
msd/start4.elf 0 → 100755
No preview for this file type
recovery/bootcode4.bin 0 → 100644
No preview for this file type
recovery/config.txt 0 → 100644
  1 +uart_2ndstage=1
recovery/pieeprom.bin 0 → 100644
No preview for this file type
recovery/pieeprom.sig 0 → 100644
  1 +14362fccbe836696bffea7e3b6eeb1b52c29fe9361a2851d08cd11869b43cb91
win32/install_script.nsi
@@ -95,6 +95,7 @@ Section &quot;Raspberry Pi USB Boot&quot; Sec_rpiboot @@ -95,6 +95,7 @@ Section &quot;Raspberry Pi USB Boot&quot; Sec_rpiboot
95 95
96 File /r redist 96 File /r redist
97 File /r ..\msd 97 File /r ..\msd
  98 + File /r ..\recovery
98 99
99 DetailPrint "Installing BCM2708 driver..." 100 DetailPrint "Installing BCM2708 driver..."
100 ExecWait '"$INSTDIR\redist\wdi-simple.exe" -n "Raspberry Pi USB boot" -v 0x0a5c -p 0x2763 -t 0' $0 101 ExecWait '"$INSTDIR\redist\wdi-simple.exe" -n "Raspberry Pi USB boot" -v 0x0a5c -p 0x2763 -t 0' $0
@@ -103,6 +104,10 @@ Section &quot;Raspberry Pi USB Boot&quot; Sec_rpiboot @@ -103,6 +104,10 @@ Section &quot;Raspberry Pi USB Boot&quot; Sec_rpiboot
103 DetailPrint "Installing BCM2710 driver..." 104 DetailPrint "Installing BCM2710 driver..."
104 ExecWait '"$INSTDIR\redist\wdi-simple.exe" -n "Raspberry Pi USB boot" -v 0x0a5c -p 0x2764 -t 0' $0 105 ExecWait '"$INSTDIR\redist\wdi-simple.exe" -n "Raspberry Pi USB boot" -v 0x0a5c -p 0x2764 -t 0' $0
105 DetailPrint "Driver install returned $0" 106 DetailPrint "Driver install returned $0"
  107 +
  108 + DetailPrint "Installing BCM2711 driver..."
  109 + ExecWait '"$INSTDIR\redist\wdi-simple.exe" -n "Raspberry Pi USB boot" -v 0x0a5c -p 0x2711 -t 0' $0
  110 + DetailPrint "Driver install returned $0"
106 111
107 File cyggcc_s-1.dll 112 File cyggcc_s-1.dll
108 File cygusb-1.0.dll 113 File cygusb-1.0.dll
@@ -139,6 +144,7 @@ Section &quot;Uninstall&quot; @@ -139,6 +144,7 @@ Section &quot;Uninstall&quot;
139 144
140 RmDir /r /REBOOTOK $INSTDIR\redist 145 RmDir /r /REBOOTOK $INSTDIR\redist
141 RmDir /r /REBOOTOK $INSTDIR\msd 146 RmDir /r /REBOOTOK $INSTDIR\msd
  147 + RmDir /r /REBOOTOK $INSTDIR\recovery
142 RmDir /r /REBOOTOK $INSTDIR\usb_driver 148 RmDir /r /REBOOTOK $INSTDIR\usb_driver
143 149
144 Delete $INSTDIR\Uninstall.exe 150 Delete $INSTDIR\Uninstall.exe
win32/rpiboot_setup.exe
No preview for this file type