PageRenderTime 25ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/sys/src/boot/pc/sub.c

https://bitbucket.org/AndreasBWagner/plan9front
C | 420 lines | 346 code | 74 blank | 0 comment | 70 complexity | cb447d9308319b0f2fdb6dbc12ca64bc MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0, 0BSD, MPL-2.0-no-copyleft-exception, Unlicense
  1. #include <u.h>
  2. #include <a.out.h>
  3. #include "fns.h"
  4. #include "mem.h"
  5. void
  6. memset(void *dst, int v, int n)
  7. {
  8. uchar *d = dst;
  9. while(n > 0){
  10. *d++ = v;
  11. n--;
  12. }
  13. }
  14. void
  15. memmove(void *dst, void *src, int n)
  16. {
  17. uchar *d = dst;
  18. uchar *s = src;
  19. if(d < s){
  20. while(n-- > 0)
  21. *d++ = *s++;
  22. } else if(d > s){
  23. s += n;
  24. d += n;
  25. while(n-- > 0)
  26. *--d = *--s;
  27. }
  28. }
  29. int
  30. memcmp(void *src, void *dst, int n)
  31. {
  32. uchar *d = dst;
  33. uchar *s = src;
  34. int r = 0;
  35. while(n-- > 0)
  36. if(r = (*d++ - *s++))
  37. break;
  38. return r;
  39. }
  40. int
  41. strlen(char *s)
  42. {
  43. char *p = s;
  44. while(*p)
  45. p++;
  46. return p - s;
  47. }
  48. char*
  49. strchr(char *s, int c)
  50. {
  51. for(; *s; s++)
  52. if(*s == c)
  53. return s;
  54. return 0;
  55. }
  56. char*
  57. strrchr(char *s, int c)
  58. {
  59. char *r = 0;
  60. while(s = strchr(s, c))
  61. r = s++;
  62. return r;
  63. }
  64. void
  65. print(char *s)
  66. {
  67. while(*s)
  68. putc(*s++);
  69. }
  70. int
  71. readn(void *f, void *data, int len)
  72. {
  73. uchar *p, *e;
  74. putc(' ');
  75. p = data;
  76. e = p + len;
  77. while(p < e){
  78. if(((ulong)p & 0xF000) == 0){
  79. putc('\b');
  80. putc(hex[((ulong)p>>16)&0xF]);
  81. }
  82. if((len = read(f, p, e - p)) <= 0)
  83. break;
  84. p += len;
  85. }
  86. putc('\b');
  87. return p - (uchar*)data;
  88. }
  89. static int
  90. readline(void *f, char buf[64])
  91. {
  92. static char white[] = "\t ";
  93. char *p;
  94. p = buf;
  95. do{
  96. if(!f)
  97. putc('>');
  98. while(p < buf + 64-1){
  99. if(!f){
  100. putc(*p = getc());
  101. if(*p == '\r')
  102. putc('\n');
  103. else if(*p == '\b' && p > buf){
  104. p--;
  105. continue;
  106. }
  107. }else if(read(f, p, 1) <= 0)
  108. return 0;
  109. if(p == buf && strchr(white, *p))
  110. continue;
  111. if(strchr(crnl, *p))
  112. break;
  113. p++;
  114. }
  115. while(p > buf && strchr(white, p[-1]))
  116. p--;
  117. }while(p == buf);
  118. *p = 0;
  119. return p - buf;
  120. }
  121. static int
  122. timeout(int ms)
  123. {
  124. while(ms > 0){
  125. if(gotc())
  126. return 1;
  127. usleep(100000);
  128. ms -= 100;
  129. }
  130. return 0;
  131. }
  132. #define BOOTLINE ((char*)CONFADDR)
  133. #define BOOTLINELEN 64
  134. #define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN))
  135. #define BOOTARGSLEN (4096-0x200-BOOTLINELEN)
  136. char *confend;
  137. static void apmconf(int);
  138. static void e820conf(void);
  139. static int
  140. delconf(char *s)
  141. {
  142. char *p, *e;
  143. for(p = BOOTARGS; p < confend; p = e){
  144. for(e = p+1; e < confend; e++){
  145. if(*e == '\n'){
  146. e++;
  147. break;
  148. }
  149. }
  150. if(!memcmp(p, s, strlen(s))){
  151. memmove(p, e, confend - e);
  152. confend -= e - p;
  153. *confend = 0;
  154. return 1;
  155. }
  156. }
  157. return 0;
  158. }
  159. char*
  160. configure(void *f, char *path)
  161. {
  162. char line[64], *kern, *s, *p;
  163. int inblock, n;
  164. Clear:
  165. kern = 0;
  166. inblock = 0;
  167. memset(BOOTLINE, 0, BOOTLINELEN);
  168. confend = BOOTARGS;
  169. memset(confend, 0, BOOTARGSLEN);
  170. e820conf();
  171. Loop:
  172. while(readline(f, line) > 0){
  173. if(*line == 0 || strchr("#;=", *line))
  174. continue;
  175. if(*line == '['){
  176. inblock = memcmp("[common]", line, 8);
  177. continue;
  178. }
  179. if(!memcmp("boot", line, 5))
  180. break;
  181. if(!memcmp("clear", line, 5)){
  182. if(line[5] == 0){
  183. print("ok");
  184. print(crnl);
  185. goto Clear;
  186. } else if(line[5] == ' ' && delconf(line+6)){
  187. print("ok");
  188. print(crnl);
  189. }
  190. continue;
  191. }
  192. if(inblock || (p = strchr(line, '=')) == nil)
  193. continue;
  194. *p++ = 0;
  195. delconf(line);
  196. if(!memcmp("apm", line, 3)){
  197. apmconf('0' - line[3]);
  198. continue;
  199. }
  200. if(!memcmp("bootfile", line, 8))
  201. memmove(kern = path, p, strlen(p)+1);
  202. s = confend;
  203. memmove(confend, line, n = strlen(line)); confend += n;
  204. *confend++ = '=';
  205. memmove(confend, p, n = strlen(p)); confend += n;
  206. *confend = 0;
  207. print(s); print(crnl);
  208. *confend++ = '\n';
  209. *confend = 0;
  210. }
  211. if(f){
  212. close(f);
  213. f = 0;
  214. if(kern && timeout(1000))
  215. goto Loop;
  216. }
  217. if(!kern){
  218. print("no bootfile\r\n");
  219. goto Loop;
  220. }
  221. if(p = strrchr(kern, '!'))
  222. kern = p+1;
  223. return kern;
  224. }
  225. static void
  226. hexfmt(char *s, int i, ulong a)
  227. {
  228. s += i;
  229. while(i > 0){
  230. *--s = hex[a&15];
  231. a >>= 4;
  232. i--;
  233. }
  234. }
  235. static void
  236. addconfx(char *s, int w, ulong v)
  237. {
  238. int n;
  239. n = strlen(s);
  240. memmove(confend, s, n);
  241. hexfmt(confend+n, w, v);
  242. confend += n+w;
  243. *confend = 0;
  244. }
  245. void apm(int id);
  246. static void
  247. apmconf(int id)
  248. {
  249. uchar *a;
  250. char *s;
  251. a = (uchar*)CONFADDR;
  252. memset(a, 0, 20);
  253. apm(id);
  254. if(memcmp(a, "APM", 4))
  255. return;
  256. s = confend;
  257. addconfx("apm", 1, id);
  258. addconfx("=ax=", 4, *((ushort*)(a+4)));
  259. addconfx(" ebx=", 8, *((ulong*)(a+12)));
  260. addconfx(" cx=", 4, *((ushort*)(a+6)));
  261. addconfx(" dx=", 4, *((ushort*)(a+8)));
  262. addconfx(" di=", 4, *((ushort*)(a+10)));
  263. addconfx(" esi=", 8, *((ulong*)(a+16)));
  264. print(s); print(crnl);
  265. *confend++ = '\n';
  266. *confend = 0;
  267. }
  268. ulong e820(ulong bx, void *p);
  269. static void
  270. e820conf(void)
  271. {
  272. struct {
  273. uvlong base;
  274. uvlong len;
  275. ulong typ;
  276. ulong ext;
  277. } e;
  278. uvlong v;
  279. ulong bx;
  280. char *s;
  281. memset(&e, 0, sizeof(e));
  282. if((bx = e820(0, &e)) == 0)
  283. return;
  284. s = confend;
  285. memmove(confend, "e820=", 5);
  286. confend += 5;
  287. do{
  288. if(e.typ == 1 && (e.ext & 1) == 0 && e.len){
  289. v = e.base;
  290. addconfx("", 8, v>>32);
  291. addconfx("", 8, v&0xffffffff);
  292. v = e.base + e.len;
  293. addconfx(" ", 8, v>>32);
  294. addconfx("", 8, v&0xffffffff);
  295. *confend++ = ' ';
  296. }
  297. memset(&e, 0, sizeof(e));
  298. } while(bx = e820(bx, &e));
  299. *confend = 0;
  300. print(s); print(crnl);
  301. *confend++ = '\n';
  302. *confend = 0;
  303. }
  304. static ushort
  305. beswab(ushort s)
  306. {
  307. uchar *p;
  308. p = (uchar*)&s;
  309. return (p[0]<<8) | p[1];
  310. }
  311. static ulong
  312. beswal(ulong l)
  313. {
  314. uchar *p;
  315. p = (uchar*)&l;
  316. return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
  317. }
  318. void a20(void);
  319. char*
  320. bootkern(void *f)
  321. {
  322. uchar *e, *d, *t;
  323. ulong n;
  324. Exec ex;
  325. a20();
  326. if(readn(f, &ex, sizeof(ex)) != sizeof(ex))
  327. return "bad header";
  328. if(beswal(ex.magic) != I_MAGIC)
  329. return "bad magic";
  330. e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
  331. t = e;
  332. n = beswal(ex.text);
  333. if(readn(f, t, n) != n)
  334. goto Error;
  335. d = (uchar*)PGROUND((ulong)t + n);
  336. n = beswal(ex.data);
  337. if(readn(f, d, n) != n)
  338. goto Error;
  339. close(f);
  340. unload();
  341. print("boot");
  342. print(crnl);
  343. jump(e);
  344. Error:
  345. return "i/o error";
  346. }