boot.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* $OpenBSD: boot.c,v 1.43 2014/02/19 22:02:15 miod Exp $ */
  2. /*
  3. * Copyright (c) 2003 Dale Rahn
  4. * Copyright (c) 1997,1998 Michael Shalayeff
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. *
  28. */
  29. #include <sys/param.h>
  30. #include <sys/reboot.h>
  31. #include <sys/stat.h>
  32. #include <libsa.h>
  33. #include <lib/libsa/loadfile.h>
  34. #include <lib/libkern/funcs.h>
  35. #include <stand/boot/bootarg.h>
  36. #include "cmd.h"
  37. #ifndef KERNEL
  38. #define KERNEL "/bsd"
  39. #endif
  40. char prog_ident[40];
  41. char *progname = "BOOT";
  42. extern const char version[];
  43. struct cmd_state cmd;
  44. /* bootprompt can be set by MD code to avoid prompt first time round */
  45. int bootprompt = 1;
  46. char *kernelfile = KERNEL; /* can be changed by MD code */
  47. int boottimeout = 5; /* can be changed by MD code */
  48. char rnddata[BOOTRANDOM_MAX];
  49. void
  50. boot(dev_t bootdev)
  51. {
  52. int fd;
  53. int try = 0, st;
  54. u_long marks[MARK_MAX];
  55. machdep();
  56. snprintf(prog_ident, sizeof(prog_ident),
  57. ">> OpenBSD/" MACHINE " %s %s", progname, version);
  58. printf("%s\n", prog_ident);
  59. devboot(bootdev, cmd.bootdev);
  60. strlcpy(cmd.image, kernelfile, sizeof(cmd.image));
  61. cmd.boothowto = 0;
  62. cmd.conf = "/etc/boot.conf";
  63. cmd.addr = (void *)DEFAULT_KERNEL_ADDRESS;
  64. cmd.timeout = boottimeout;
  65. st = read_conf();
  66. if (!bootprompt)
  67. snprintf(cmd.path, sizeof cmd.path, "%s:%s",
  68. cmd.bootdev, cmd.image);
  69. while (1) {
  70. /* no boot.conf, or no boot cmd in there */
  71. if (bootprompt && st <= 0) {
  72. do {
  73. printf("boot> ");
  74. } while(!getcmd());
  75. }
  76. loadrandom(BOOTRANDOM, rnddata, sizeof(rnddata));
  77. #ifdef MDRANDOM
  78. mdrandom(rnddata, sizeof(rnddata));
  79. #endif
  80. st = 0;
  81. bootprompt = 1; /* allow reselect should we fail */
  82. printf("booting %s: ", cmd.path);
  83. marks[MARK_START] = (u_long)cmd.addr;
  84. if ((fd = loadfile(cmd.path, marks, LOAD_ALL)) != -1) {
  85. close(fd);
  86. break;
  87. }
  88. kernelfile = KERNEL;
  89. try++;
  90. strlcpy(cmd.image, kernelfile, sizeof(cmd.image));
  91. printf(" failed(%d). will try %s\n", errno, kernelfile);
  92. if (try < 2) {
  93. if (cmd.timeout > 0)
  94. cmd.timeout++;
  95. } else {
  96. if (cmd.timeout)
  97. printf("Turning timeout off.\n");
  98. cmd.timeout = 0;
  99. }
  100. }
  101. /* exec */
  102. run_loadfile(marks, cmd.boothowto);
  103. }
  104. void
  105. loadrandom(char *name, char *buf, size_t buflen)
  106. {
  107. char path[MAXPATHLEN];
  108. struct stat sb;
  109. int fd, i;
  110. #define O_RDONLY 0
  111. /* Extract the device name from the kernel we are loading. */
  112. for (i = 0; i < sizeof(cmd.path); i++) {
  113. if (cmd.path[i] == ':') {
  114. strlcpy(path, cmd.path, i + 1);
  115. snprintf(path + i, sizeof(path) - i, ":%s", name);
  116. break;
  117. } else if (cmd.path[i] == '\0') {
  118. snprintf(path, sizeof path, "%s:%s",
  119. cmd.bootdev, name);
  120. break;
  121. }
  122. }
  123. fd = open(path, O_RDONLY);
  124. if (fd == -1) {
  125. if (errno != EPERM)
  126. printf("cannot open %s: %s\n", path, strerror(errno));
  127. return;
  128. }
  129. if (fstat(fd, &sb) == -1 ||
  130. sb.st_uid != 0 ||
  131. (sb.st_mode & (S_IWOTH|S_IROTH)))
  132. goto fail;
  133. (void) read(fd, buf, buflen);
  134. fail:
  135. close(fd);
  136. }