Commit be1bc6424999ba0a013c129bf57bfba2a60b290a
Committed by
Gordon Hollingworth
1 parent
8d709206
Add buildroot.elf installation and cmdline parameters
Showing
2 changed files
with
94 additions
and
33 deletions
Makefile
| @@ -6,6 +6,7 @@ install: rpiboot | @@ -6,6 +6,7 @@ install: rpiboot | ||
| 6 | mkdir -p /usr/share/rpiboot | 6 | mkdir -p /usr/share/rpiboot |
| 7 | cp usbbootcode.bin /usr/share/rpiboot | 7 | cp usbbootcode.bin /usr/share/rpiboot |
| 8 | cp msd.elf /usr/share/rpiboot | 8 | cp msd.elf /usr/share/rpiboot |
| 9 | + cp buildroot.elf /usr/share/rpiboot | ||
| 9 | 10 | ||
| 10 | clean: | 11 | clean: |
| 11 | rm rpiboot | 12 | rm rpiboot |
main.c
| @@ -5,6 +5,30 @@ | @@ -5,6 +5,30 @@ | ||
| 5 | 5 | ||
| 6 | #include <unistd.h> | 6 | #include <unistd.h> |
| 7 | 7 | ||
| 8 | +int verbose = 0; | ||
| 9 | + | ||
| 10 | +void usage(int error) | ||
| 11 | +{ | ||
| 12 | + FILE * dest = error ? stderr : stdout; | ||
| 13 | + | ||
| 14 | + fprintf(dest, "Usage: rpiboot\n"); | ||
| 15 | + fprintf(dest, " or: rpiboot -b fatimage\n"); | ||
| 16 | + fprintf(dest, "Boot a Raspberry Pi Model A or Compute Module through USB\n"); | ||
| 17 | + fprintf(dest, "\n"); | ||
| 18 | + fprintf(dest, "rpiboot : Boot the device into Mass Storage Device mode\n"); | ||
| 19 | + fprintf(dest, "rpiboot -b fatimage : Boot the device into a buildroot linux image\n"); | ||
| 20 | + fprintf(dest, "\n"); | ||
| 21 | + fprintf(dest, "Further options:\n"); | ||
| 22 | + fprintf(dest, " -x executable : Autoexecute function\n"); | ||
| 23 | + fprintf(dest, " This option is used to trigger the execution of a\n"); | ||
| 24 | + fprintf(dest, " script after finishing the USB boot process\n"); | ||
| 25 | + fprintf(dest, " -l : Sit in a loop permanently\n"); | ||
| 26 | + fprintf(dest, " -v : Verbose output"); | ||
| 27 | + fprintf(dest, " -h : This help\n"); | ||
| 28 | + exit(-1); | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | + | ||
| 8 | int Initialize_Device(libusb_context ** ctx, libusb_device_handle ** usb_device) | 32 | int Initialize_Device(libusb_context ** ctx, libusb_device_handle ** usb_device) |
| 9 | { | 33 | { |
| 10 | int ret = 0; | 34 | int ret = 0; |
| @@ -33,7 +57,8 @@ int ep_write(unsigned char *buf, int len, libusb_device_handle * usb_device) | @@ -33,7 +57,8 @@ int ep_write(unsigned char *buf, int len, libusb_device_handle * usb_device) | ||
| 33 | int a_len; | 57 | int a_len; |
| 34 | 58 | ||
| 35 | ret = libusb_bulk_transfer(usb_device, 0x01, buf, len, &a_len, 100000); | 59 | ret = libusb_bulk_transfer(usb_device, 0x01, buf, len, &a_len, 100000); |
| 36 | - printf("libusb_bulk_transfer returned %d\n", ret); | 60 | + if(verbose) |
| 61 | + printf("libusb_bulk_transfer returned %d\n", ret); | ||
| 37 | 62 | ||
| 38 | return a_len; | 63 | return a_len; |
| 39 | } | 64 | } |
| @@ -57,27 +82,57 @@ int main(int argc, char *argv[]) | @@ -57,27 +82,57 @@ int main(int argc, char *argv[]) | ||
| 57 | unsigned char *txbuf; | 82 | unsigned char *txbuf; |
| 58 | int size; | 83 | int size; |
| 59 | int retcode; | 84 | int retcode; |
| 60 | - FILE *fp1, *fp2; | 85 | + int last_serial = -1; |
| 86 | + FILE *fp1, *fp2, *fp; | ||
| 61 | char def1[] = "/usr/share/rpiboot/usbbootcode.bin"; | 87 | char def1[] = "/usr/share/rpiboot/usbbootcode.bin"; |
| 62 | char def2[] = "/usr/share/rpiboot/msd.elf"; | 88 | char def2[] = "/usr/share/rpiboot/msd.elf"; |
| 89 | + char def3[] = "/usr/share/rpiboot/buildroot.elf"; | ||
| 63 | 90 | ||
| 64 | - char *stage1, *stage2; | ||
| 65 | - char *dir; | 91 | + char *stage1 = def1, *stage2 = def2; |
| 92 | + char *fatimage = NULL, *executable = NULL; | ||
| 93 | + int loop = 0; | ||
| 66 | 94 | ||
| 67 | struct MESSAGE_S { | 95 | struct MESSAGE_S { |
| 68 | int length; | 96 | int length; |
| 69 | unsigned char signature[20]; | 97 | unsigned char signature[20]; |
| 70 | } message; | 98 | } message; |
| 71 | 99 | ||
| 72 | - if(argc > 2) | ||
| 73 | - { | ||
| 74 | - stage1 = argv[1]; | ||
| 75 | - stage2 = argv[2]; | ||
| 76 | - } | ||
| 77 | - else | 100 | + // Skip the command name |
| 101 | + argv++; argc--; | ||
| 102 | + while(*argv) | ||
| 78 | { | 103 | { |
| 79 | - stage1 = def1; | ||
| 80 | - stage2 = def2; | 104 | + if(strcmp(*argv, "-b") == 0) |
| 105 | + { | ||
| 106 | + argv++; argc--; | ||
| 107 | + if(argc < 1) | ||
| 108 | + usage(1); | ||
| 109 | + stage1 = def1; | ||
| 110 | + stage2 = def3; | ||
| 111 | + fatimage = *argv; | ||
| 112 | + } | ||
| 113 | + else if(strcmp(*argv, "-h") == 0 || strcmp(*argv, "--help") == 0) | ||
| 114 | + { | ||
| 115 | + usage(0); | ||
| 116 | + } | ||
| 117 | + else if(strcmp(*argv, "-x") == 0) | ||
| 118 | + { | ||
| 119 | + argv++; argc--; | ||
| 120 | + executable = *argv; | ||
| 121 | + } | ||
| 122 | + else if(strcmp(*argv, "-l") == 0) | ||
| 123 | + { | ||
| 124 | + loop = 1; | ||
| 125 | + } | ||
| 126 | + else if(strcmp(*argv, "-v") == 0) | ||
| 127 | + { | ||
| 128 | + verbose = 1; | ||
| 129 | + } | ||
| 130 | + else | ||
| 131 | + { | ||
| 132 | + usage(1); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + argv++; argc--; | ||
| 81 | } | 136 | } |
| 82 | 137 | ||
| 83 | fp1 = fopen(stage1, "rb"); | 138 | fp1 = fopen(stage1, "rb"); |
| @@ -108,9 +163,9 @@ int main(int argc, char *argv[]) | @@ -108,9 +163,9 @@ int main(int argc, char *argv[]) | ||
| 108 | 163 | ||
| 109 | libusb_set_debug(ctx, 0); | 164 | libusb_set_debug(ctx, 0); |
| 110 | 165 | ||
| 111 | - while (1) | 166 | + do |
| 112 | { | 167 | { |
| 113 | - FILE *fp, *fp_img = NULL; | 168 | + FILE *fp_img = NULL; |
| 114 | struct libusb_device_descriptor desc; | 169 | struct libusb_device_descriptor desc; |
| 115 | 170 | ||
| 116 | printf("Waiting for BCM2835 ...\n"); | 171 | printf("Waiting for BCM2835 ...\n"); |
| @@ -119,17 +174,26 @@ int main(int argc, char *argv[]) | @@ -119,17 +174,26 @@ int main(int argc, char *argv[]) | ||
| 119 | do | 174 | do |
| 120 | { | 175 | { |
| 121 | result = Initialize_Device(&ctx, &usb_device); | 176 | result = Initialize_Device(&ctx, &usb_device); |
| 122 | - if (result) | 177 | + if(result == 0) |
| 123 | { | 178 | { |
| 124 | - sleep(1); | 179 | + libusb_get_device_descriptor(libusb_get_device |
| 180 | + (usb_device), &desc); | ||
| 181 | + // Make sure we've re-enumerated since the last time | ||
| 182 | + if(desc.iSerialNumber == last_serial) | ||
| 183 | + { | ||
| 184 | + result = -1; | ||
| 185 | + libusb_close(usb_device); | ||
| 186 | + } | ||
| 125 | } | 187 | } |
| 126 | 188 | ||
| 189 | + if (result) | ||
| 190 | + { | ||
| 191 | + usleep(100); | ||
| 192 | + } | ||
| 127 | } | 193 | } |
| 128 | while (result); | 194 | while (result); |
| 129 | 195 | ||
| 130 | - ret = | ||
| 131 | - libusb_get_device_descriptor(libusb_get_device | ||
| 132 | - (usb_device), &desc); | 196 | + last_serial = desc.iSerialNumber; |
| 133 | printf("Found serial = %d: writing file %s\n", | 197 | printf("Found serial = %d: writing file %s\n", |
| 134 | desc.iSerialNumber, | 198 | desc.iSerialNumber, |
| 135 | desc.iSerialNumber == 0 ? stage1 : stage2); | 199 | desc.iSerialNumber == 0 ? stage1 : stage2); |
| @@ -139,20 +203,18 @@ int main(int argc, char *argv[]) | @@ -139,20 +203,18 @@ int main(int argc, char *argv[]) | ||
| 139 | message.length = ftell(fp); | 203 | message.length = ftell(fp); |
| 140 | fseek(fp, 0, SEEK_SET); | 204 | fseek(fp, 0, SEEK_SET); |
| 141 | 205 | ||
| 142 | - printf("Writing %d bytes of program data\n", message.length); | ||
| 143 | - | ||
| 144 | - if(desc.iSerialNumber == 1 && argc == 4) | 206 | + if(desc.iSerialNumber == 1 && fatimage != NULL) |
| 145 | { | 207 | { |
| 146 | // Been given a filesystem image | 208 | // Been given a filesystem image |
| 147 | - fp_img = fopen(argv[3], "rb"); | 209 | + fp_img = fopen(fatimage, "rb"); |
| 148 | if(fp_img == NULL) | 210 | if(fp_img == NULL) |
| 149 | { | 211 | { |
| 150 | - printf("Failed to open image %s\n", argv[3]); | 212 | + printf("Failed to open image %s\n", fatimage); |
| 151 | exit(-1); | 213 | exit(-1); |
| 152 | } | 214 | } |
| 153 | fseek(fp_img, 0, SEEK_END); | 215 | fseek(fp_img, 0, SEEK_END); |
| 154 | message.length += ftell(fp_img); | 216 | message.length += ftell(fp_img); |
| 155 | - printf("Adding %d bytes of binary to end of elf\n", ftell(fp_img)); | 217 | + if(verbose) printf("Adding %d bytes of binary to end of elf\n", ftell(fp_img)); |
| 156 | fseek(fp_img, 0, SEEK_SET); | 218 | fseek(fp_img, 0, SEEK_SET); |
| 157 | } | 219 | } |
| 158 | 220 | ||
| @@ -178,7 +240,7 @@ int main(int argc, char *argv[]) | @@ -178,7 +240,7 @@ int main(int argc, char *argv[]) | ||
| 178 | size); | 240 | size); |
| 179 | exit(-1); | 241 | exit(-1); |
| 180 | } | 242 | } |
| 181 | - | 243 | + if(verbose) printf("Writing %d bytes\n", message.length); |
| 182 | size = ep_write(txbuf, message.length, usb_device); | 244 | size = ep_write(txbuf, message.length, usb_device); |
| 183 | if (size != message.length) | 245 | if (size != message.length) |
| 184 | { | 246 | { |
| @@ -187,27 +249,25 @@ int main(int argc, char *argv[]) | @@ -187,27 +249,25 @@ int main(int argc, char *argv[]) | ||
| 187 | exit(-1); | 249 | exit(-1); |
| 188 | } | 250 | } |
| 189 | 251 | ||
| 190 | - sleep(1); | ||
| 191 | - | ||
| 192 | size = | 252 | size = |
| 193 | ep_read((unsigned char *)&retcode, sizeof(retcode), | 253 | ep_read((unsigned char *)&retcode, sizeof(retcode), |
| 194 | usb_device); | 254 | usb_device); |
| 195 | 255 | ||
| 196 | if (retcode == 0) | 256 | if (retcode == 0) |
| 197 | { | 257 | { |
| 198 | - printf("Successful\n"); | ||
| 199 | - if(fp==fp2) | 258 | + if(verbose) printf("Successful\n"); |
| 259 | + | ||
| 260 | + if(fp == fp2 && executable) | ||
| 200 | { | 261 | { |
| 201 | - printf("Raspberry Pi is now a mass storage device, use lsblk to find it\n"); | ||
| 202 | - exit(0); | 262 | + system(executable); |
| 203 | } | 263 | } |
| 204 | } | 264 | } |
| 205 | else | 265 | else |
| 206 | printf("Failed : 0x%x", retcode); | 266 | printf("Failed : 0x%x", retcode); |
| 207 | 267 | ||
| 208 | - sleep(1); | ||
| 209 | libusb_close(usb_device); | 268 | libusb_close(usb_device); |
| 210 | } | 269 | } |
| 270 | + while(fp == fp1 || loop); | ||
| 211 | 271 | ||
| 212 | libusb_exit(ctx); | 272 | libusb_exit(ctx); |
| 213 | 273 |