bitsyload.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <u.h>
  2. #include <libc.h>
  3. enum
  4. {
  5. Magic= 0x5a5abeef,
  6. };
  7. typedef struct Method Method;
  8. struct Method {
  9. char *verb;
  10. char *part;
  11. char *file;
  12. };
  13. Method method[] =
  14. {
  15. { "k", "/dev/flash/kernel", "/sys/src/9/bitsy/9bitsy" },
  16. { "r", "/dev/flash/ramdisk", "/sys/src/9/bitsy/paqdisk" },
  17. { "u", "/dev/flash/user", "/sys/src/9/bitsy/user" },
  18. };
  19. void
  20. leputl(uchar *p, ulong x)
  21. {
  22. *p++ = x;
  23. *p++ = x>>8;
  24. *p++ = x>>16;
  25. *p = x>>24;
  26. }
  27. void
  28. usage(void)
  29. {
  30. fprint(2, "usage: %s k|r [file]\n", argv0);
  31. exits("usage");
  32. }
  33. void
  34. main(int argc, char **argv)
  35. {
  36. char *file;
  37. int ctl, in, out;
  38. int i, n;
  39. uchar *buf;
  40. char ctlfile[64];
  41. char ctldata[1024];
  42. char *args[10];
  43. Dir *d;
  44. ulong nsects, sectsize;
  45. Method *m;
  46. ARGBEGIN {
  47. } ARGEND;
  48. if(argc == 0)
  49. usage();
  50. for(m = method; m < method + nelem(method); m++)
  51. if(strcmp(argv[0], m->verb) == 0)
  52. break;
  53. if(m == method + nelem(method))
  54. usage();
  55. if(argc < 2)
  56. file = m->file;
  57. else
  58. file = argv[1];
  59. in = open(file, OREAD);
  60. if(in < 0)
  61. sysfatal("%s: %r", file);
  62. d = dirfstat(in);
  63. if(d == nil)
  64. sysfatal("stating %s: %r", file);
  65. out = open(m->part, OWRITE);
  66. if(out < 0)
  67. sysfatal("%s: %r", m->part);
  68. sprint(ctlfile, "%sctl", m->part);
  69. ctl = open(ctlfile, ORDWR);
  70. if(ctl < 0)
  71. sysfatal("%s: %r", ctlfile);
  72. i = read(ctl, ctldata, sizeof(ctldata) - 1);
  73. if (i <= 0)
  74. sysfatal("%s: %r", ctlfile);
  75. ctldata[i] = '\0';
  76. i = tokenize(ctldata, args, nelem(args));
  77. if(i < 7)
  78. sysfatal("bad flash geometry");
  79. nsects = atoi(args[5]);
  80. sectsize = atoi(args[6]);
  81. if(nsects < 3)
  82. sysfatal("unreasonable value for nsects: %lud", nsects);
  83. if(sectsize < 512)
  84. sysfatal("unreasonable value for sectsize: %lud", sectsize);
  85. /* allocate a buffer and read in the whole file */
  86. n = d->length;
  87. buf = malloc(n + sectsize);
  88. if(buf == nil)
  89. sysfatal("not enough room to read in file: %r");
  90. print("reading %d bytes of %s\n", n, file);
  91. if(readn(in, buf, n) != n)
  92. sysfatal("error reading file: %r");
  93. close(in);
  94. memset(buf + n, 0, sectsize);
  95. n = ((n+sectsize-1)/sectsize)*sectsize;
  96. if (nsects * sectsize < n)
  97. sysfatal("file too large (%d) for partition (%lud)", n, nsects * sectsize);
  98. print("erasing %s\n", m->part);
  99. if(fprint(ctl, "erase") < 0)
  100. sysfatal("erase %s: %r", ctlfile);
  101. close(ctl);
  102. print("writing %s\n", m->part);
  103. for (i = 0; i < n; i += sectsize)
  104. if(write(out, buf + i, sectsize) != sectsize)
  105. sysfatal("writing %s at %d: %r", file, i);
  106. print("write done\n");
  107. close(in);
  108. close(out);
  109. }