//************************************************************* // // Parse the GPS buffer and store information in the struct. // // You may notice this: (index%BUFFERSIZE) in multiple places. // If our index exceeds our BUFFERSIZE then the modulus will // allow us to wrap around and start at the beginning of our // circular array. // //************************************************************* void parse_gps_data(void) { uint32_t index = 0; char *buffer = gps_buffer; while (index <= BUFFERSIZE){ if (*(buffer + index) != '$'){ index++; continue; } parse_code(buffer, ++index); // break; } }
int generate_for_item(Pool *pool, FILE *out, AstFor *p, ListNode *item, int *need_comma) { Scope *scope = scope_new(pool, p->scope); ListBuilder code = list_builder_init(pool); if (dynamic_ok(p->filter) && !test_filter(p->filter, ast_to_outline_item(item->d))) return 1; if (p->list && *need_comma) CHECK(file_putc(out, ',')); *need_comma = 1; scope_add(scope, pool, p->item, item->d); CHECK(parse_code(pool, &p->code, scope, out_list_builder(&code))); CHECK(generate_code(pool, out, code.first)); return 1; }
void parser::parse_text( std::istream &in ) { while ( !in.eof() && in ) { int c = in.get(); if ( std::char_traits<char>::not_eof( c ) ) { if ( c == '[' ) { switch ( in.peek() ) { case '[': _func.push_text(); parse_expr( in ); break; case '%': _func.push_text( true ); parse_code( in ); break; case '#': _func.push_text( true ); parse_directive( in ); break; case '/': _func.push_text( true ); parse_comment( in ); break; default: _func.add( static_cast<char>( c ) ); break; } } else _func.add( static_cast<char>( c ) ); } } _func.push_text(); }
int main(int argc, char* argv[]) { int input_len; char *code; bool code_ok; code = argv[1]; code_ok = validate_code_input(code); if (!code_ok) { exit(EXIT_FAILURE); } // This does it for both code length and program length input_len = strlen(code); cmd_t *program = parse_code(argv[1], input_len); execute_program(program, input_len); return 0; }
int generate_macro_call(Pool *pool, FILE *out, AstMacroCall *p) { ListNode *call_input; ListNode *macro_input; Scope *scope = scope_new(pool, p->macro->scope); ListBuilder code = list_builder_init(pool); /* Assign values to all inputs: */ macro_input = p->macro->inputs; call_input = p->inputs; while (macro_input && call_input) { AstCodeText *name = macro_input->d.p; scope_add(scope, pool, name->code, call_input->d); macro_input = macro_input->next; call_input = call_input->next; } CHECK(parse_code(pool, &p->macro->code, scope, out_list_builder(&code))); CHECK(generate_code(pool, out, code.first)); return 1; }
static error_t parse_opt(int k, char *arg, struct argp_state *state) { char *p; long key; int rc; switch (k) { case 'v': debug++; break; case 't': test++; break; case 'c': clear++; break; case 'D': delay = atoi(arg); break; case 'P': period = atoi(arg); break; case 'd': devicename = arg; break; case 's': devclass = arg; break; case 'r': readtable++; break; case 'w': { char *name = NULL; rc = parse_keyfile(arg, &name); if (rc) goto err_inval; if (name) fprintf(stderr, "Read %s table\n", name); break; } case 'a': { rc = parse_cfgfile(arg); if (rc) goto err_inval; break; } case 'k': p = strtok(arg, ":="); do { if (!p) goto err_inval; nextkey->codes[0] = strtoul(p, NULL, 0); if (errno) goto err_inval; p = strtok(NULL, ",;"); if (!p) goto err_inval; key = parse_code(p); if (key == -1) { key = strtol(p, NULL, 0); if (errno) goto err_inval; } nextkey->codes[1] = key; if (debug) fprintf(stderr, "scancode 0x%04x=%u\n", nextkey->codes[0], nextkey->codes[1]); nextkey->next = calloc(1, sizeof(keys)); if (!nextkey->next) { perror("No memory!\n"); return ENOMEM; } nextkey = nextkey->next; p = strtok(NULL, ":="); } while (p); break; case 'p': p = strtok(arg, ",;"); do { if (!p) goto err_inval; if (!strcasecmp(p,"rc5") || !strcasecmp(p,"rc-5")) ch_proto |= RC_5; else if (!strcasecmp(p,"rc6") || !strcasecmp(p,"rc-6")) ch_proto |= RC_6; else if (!strcasecmp(p,"nec")) ch_proto |= NEC; else if (!strcasecmp(p,"jvc")) ch_proto |= JVC; else if (!strcasecmp(p,"sony")) ch_proto |= SONY; else if (!strcasecmp(p,"sanyo")) ch_proto |= SANYO; else if (!strcasecmp(p,"lirc")) ch_proto |= LIRC; else if (!strcasecmp(p,"rc-5-sz")) ch_proto |= RC_5_SZ; else if (!strcasecmp(p,"sharp")) ch_proto |= RC_5_SZ; else if (!strcasecmp(p,"mce-kbd")) ch_proto |= RC_5_SZ; else if (!strcasecmp(p,"xmp")) ch_proto |= XMP; else if (!strcasecmp(p,"all")) ch_proto |= ~0; else goto err_inval; p = strtok(NULL, ",;"); } while (p); break; default: return ARGP_ERR_UNKNOWN; } return 0; err_inval: fprintf(stderr, "Invalid parameter(s)\n"); return ARGP_ERR_UNKNOWN; }
static error_t parse_keyfile(char *fname, char **table) { FILE *fin; int value, line = 0; char *scancode, *keycode, s[2048]; *table = NULL; if (debug) fprintf(stderr, "Parsing %s keycode file\n", fname); fin = fopen(fname, "r"); if (!fin) { return errno; } while (fgets(s, sizeof(s), fin)) { char *p = s; line++; while (*p == ' ' || *p == '\t') p++; if (line==1 && p[0] == '#') { p++; p = strtok(p, "\n\t =:"); do { if (!p) goto err_einval; if (!strcmp(p, "table")) { p = strtok(NULL,"\n, "); if (!p) goto err_einval; *table = malloc(strlen(p) + 1); strcpy(*table, p); } else if (!strcmp(p, "type")) { p = strtok(NULL, " ,\n"); do { if (!p) goto err_einval; if (!strcasecmp(p,"rc5") || !strcasecmp(p,"rc-5")) ch_proto |= RC_5; else if (!strcasecmp(p,"rc6") || !strcasecmp(p,"rc-6")) ch_proto |= RC_6; else if (!strcasecmp(p,"nec")) ch_proto |= NEC; else if (!strcasecmp(p,"jvc")) ch_proto |= JVC; else if (!strcasecmp(p,"sony")) ch_proto |= SONY; else if (!strcasecmp(p,"sanyo")) ch_proto |= SANYO; else if (!strcasecmp(p,"rc-5-sz")) ch_proto |= RC_5_SZ; else if (!strcasecmp(p,"sharp")) ch_proto |= SHARP; else if (!strcasecmp(p,"mce-kbd")) ch_proto |= MCE_KBD; else if (!strcasecmp(p,"xmp")) ch_proto |= XMP; else if (!strcasecmp(p,"other") || !strcasecmp(p,"unknown")) ch_proto |= OTHER; else { fprintf(stderr, "Protocol %s invalid\n", p); goto err_einval; } p = strtok(NULL, " ,\n"); } while (p); } else { goto err_einval; } p = strtok(NULL, "\n\t =:"); } while (p); continue; } if (*p == '\n' || *p == '#') continue; scancode = strtok(p, "\n\t =:"); if (!scancode) goto err_einval; if (!strcasecmp(scancode, "scancode")) { scancode = strtok(NULL, "\n\t =:"); if (!scancode) goto err_einval; } keycode = strtok(NULL, "\n\t =:("); if (!keycode) goto err_einval; if (debug) fprintf(stderr, "parsing %s=%s:", scancode, keycode); value = parse_code(keycode); if (debug) fprintf(stderr, "\tvalue=%d\n", value); if (value == -1) { value = strtol(keycode, NULL, 0); if (errno) perror("value"); } nextkey->codes[0] = (unsigned) strtoul(scancode, NULL, 0); nextkey->codes[1] = (unsigned) value; nextkey->next = calloc(1, sizeof(*nextkey)); if (!nextkey->next) { perror("parse_keyfile"); return ENOMEM; } nextkey = nextkey->next; } fclose(fin); return 0; err_einval: fprintf(stderr, "Invalid parameter on line %d of %s\n", line, fname); return EINVAL; }
static int parse_primary(struct peg_grammar_parser *pgp, struct peg_cursor *pc, int *prip) { struct peg_grammar *peg = pgp->peg; int pri; int rv; int match = -1; struct peg_cursor npc = *pc; int prefix = PEG_ATTR_NONE; int suffix = PEG_ATTR_NONE; int action = PEG_ACT_NONE; struct raw r = { 0, NULL }; struct peg_node *pn; if ( string_match(pgp, "&", &npc) ) prefix = PEG_ATTR_AND; else if ( string_match(pgp, "!", &npc) ) prefix = PEG_ATTR_NOT; if ( (rv = parse_id_and_not_arrow(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else if ( (rv = parse_paren_expr(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else if ( (rv = parse_literal(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else if ( (rv = parse_class(pgp, &npc, &match)) != 0 ) { if ( rv < 0 ) goto err; } else { if ( prefix == PEG_ATTR_NONE ) return 0; pgp->err = PEG_ERR_BAD_PRIMARY; pgp->eloc = *pc; return -1; } pri = peg_node_new(peg, PEG_PRIMARY, pc->line); if ( pri < 0 ) { pgp->err = PEG_ERR_NOMEM; goto err; } if ( string_match(pgp, "?", &npc) ) suffix = PEG_ATTR_QUESTION; else if ( string_match(pgp, "*", &npc) ) suffix = PEG_ATTR_STAR; else if ( string_match(pgp, "+", &npc) ) suffix = PEG_ATTR_PLUS; else suffix = PEG_ATTR_NONE; rv = parse_code(pgp, &npc, &r); if ( rv < 0 ) goto err; if ( rv > 0 ) { action = PEG_ACT_CODE; } else { rv = parse_action_label(pgp, &npc, &r); if ( rv < 0 ) goto err; if ( rv > 0 ) action = PEG_ACT_LABEL; } pn = NODE(peg, pri); pn->pn_next = -1; pn->pp_match = match; pn->pp_prefix = prefix; pn->pp_suffix = suffix; pn->pp_action = action; pn->pn_action_cb = NULL; pn->pp_code = r; *pc = npc; *prip = pri; return 1; err: peg_node_free(peg, match); return -1; }
/** * Program entry point. Constructs and launches the main program object. */ int main(int argc, char *argv[]) { Pool pool = pool_init(0x10000); /* 64K block size */ Options opt = options_init(); Source *in; Scope *scope = scope_new(&pool, 0); ListBuilder code = list_builder_init(&pool); /* Read the options: */ if (!options_parse(&opt, argc, argv)) { options_usage(argv[0]); goto error; } /* Determine output file name: */ if (!string_size(opt.name_out)) { if (string_rmatch(opt.name_in, string_from_k(".ol")) != 3) { fprintf(stderr, "error: If no output file is specified, the input file name must end with \".ol\".\n"); goto error; } opt.name_out = string(opt.name_in.p, opt.name_in.end - 3); } /* Input stream: */ in = source_load(&pool, opt.name_in); if (!in) { fprintf(stderr, "error: Could not open source file \"%s\"\n", opt.name_in.p); goto error; } /* Keywords: */ scope_add(scope, &pool, string_from_k("macro"), dynamic(type_keyword, keyword_new(&pool, parse_macro))); scope_add(scope, &pool, string_from_k("outline"), dynamic(type_keyword, keyword_new(&pool, parse_outline))); scope_add(scope, &pool, string_from_k("union"), dynamic(type_keyword, keyword_new(&pool, parse_union))); scope_add(scope, &pool, string_from_k("map"), dynamic(type_keyword, keyword_new(&pool, parse_map))); scope_add(scope, &pool, string_from_k("for"), dynamic(type_keyword, keyword_new(&pool, parse_for))); scope_add(scope, &pool, string_from_k("include"), dynamic(type_keyword, keyword_new(&pool, parse_include))); /* Do outline2c stuff: */ if (!parse_code(&pool, in, scope, out_list_builder(&code))) goto error; if (opt.debug) { printf("--- AST: ---\n"); dump_code(code.first, 0); printf("\n"); } if (!main_generate(&pool, code.first, &opt)) goto error; /* Clean up: */ pool_free(&pool); return 0; error: pool_free(&pool); return 1; }
/* Creates the contents of the various parts of the object file. */ static int populateparts(blueprint const *bp, int codetype, char const *filename ) { if (bp->parts[P_COMMENT].shtype) { bp->parts[P_COMMENT].shname = ".comment"; bp->parts[P_COMMENT].size = sizeof comment; xstrndup(bp->parts[P_COMMENT].part, comment, sizeof comment); } if (bp->parts[P_SYMTAB].shtype) addtosymtab(bp->parts + P_SYMTAB, srcfilename, STB_LOCAL, STT_FILE, SHN_ABS); mach_buf = bp->parts[P_TEXT].part; mach_size = bp->parts[P_TEXT].size; parse_code( bp, filename ); bp->parts[P_TEXT].size = pos; bp->parts[P_TEXT].part = mach_buf; bp->parts[P_DATA].size = 1000; if (!(bp->parts[P_DATA].part = calloc(1000, 1))) return 0; bp->parts[P_DATA].part = mach_buf; addrelocations(bp, ET_EXEC, functionname); fillparts(bp); if (!computeoffsets(bp)) return 0; #ifdef _DEBUG printf("0x%x\n", bp->parts[P_TEXT].addr ); #endif int i, addr; char call[] = { 0xe8, 0xde, 0xad, 0xc0, 0xde }; char mov[] = { 0xbf, 0xde, 0xad, 0xc0, 0xde }; char* text = bp->parts[P_TEXT].part; for(i = 0; i < pos; i++) { if(!memcmp( text+i, call, 5 )) { addr = exec_table_pos - (i + 5); memcpy( text+i+1, &addr, sizeof(int)); } } for(i = 0; i < pos; i++) { if(!memcmp( text+i, mov, 5 )) { addr = table_pos + bp->parts[P_TEXT].addr; memcpy( text+i+1, &addr, sizeof(int)); } } for(i = 0; i < LEN; i++) { table[i] += bp->parts[P_TEXT].addr; memcpy( text + table_pos + (i*4), &table[i], sizeof(int)); #ifdef _DEBUG printf("table[%d]:\t0x%x\n", i, table[i] ); #endif } createfixups(bp, codetype, functionname); completeparts(bp); return 1; }
void parser_test() { const wchar_t *gmr_txt; cfgConfig_t *cfg; char buf[1024]; AR_printf(L"%ls\r\n", L"Please enter pattern path!"); //__gets_chk(buf,1024); getchar(); //gmr_txt = __load_txt(DEF_PAT_PATH); gmr_txt = __load_txt(buf); if(gmr_txt == NULL) { AR_abort(); } cfg = CFG_CollectGrammarConfig(gmr_txt, &__g_report); if(cfg) { #if(1) size_t i; AR_printf(L"----------------------\r\n"); for(i = 0; i < cfg->name_cnt; ++i) { AR_printf(L"%ls : %ls : %d\r\n", cfg->name[i].name, cfg->name[i].regex, cfg->name[i].line); /* if(!LEX_InsertName(tmp_lex, cfg->name[i].name, cfg->name[i].regex)) { AR_abort(); } */ } AR_printf(L"----------------------\r\n"); for(i = 0; i < cfg->tok_cnt; ++i) { lexAction_t act; act.is_skip = cfg->tok[i].is_skip; act.priority = cfg->tok[i].lex_prec; act.value = i + 256; AR_printf(L"%ls : %ls : %d : %d\r\n", cfg->tok[i].name, cfg->tok[i].regex, cfg->tok[i].lex_prec, cfg->tok[i].tokval); /* if(!LEX_InsertRule(tmp_lex, cfg->tok[i].regex, &act)) { AR_abort(); } */ } AR_printf(L"----------------------\r\n"); for(i = 0; i < cfg->prec_cnt; ++i) { size_t k; const cfgPrec_t *prec = &cfg->prec[i]; for(k = 0; k < prec->count; ++k) { AR_printf(L"name == %ls : tok_val == %d : prec_level == %d : assoc == %d \r\n", prec->prec_tok_set[k], prec->prec_tok_val[k],prec->prec_level, prec->assoc); } } AR_printf(L"----------------------\r\n"); for(i = 0; i < cfg->rule_cnt; ++i) { AR_printf(L"%ls : %ls : %ls : %ls : line %d\r\n" , cfg->rule[i].lhs , cfg->rule[i].rhs , cfg->rule[i].prec_tok ? cfg->rule[i].prec_tok : L" " , cfg->rule[i].action_ins ? cfg->rule[i].action_ins : L" " ,cfg->rule[i].line ); } AR_printf(L"----------------------\r\n"); // arString_t *str = NULL; // CFG_ConfigToCode(cfg, str); #endif if(!cfg->has_error) { char buf[1024]; AR_printf(L"%ls\r\n", "Please enter sources path"); //gets(buf); //__gets_chk(buf,1024); //const wchar_t *input = __load_txt(DEF_SOUR_PATH); const wchar_t *input = __load_txt(buf); parse_code(cfg, input); AR_DEL(input); } }else { AR_abort(); } if(cfg)CFG_DestroyGrammarConfig(cfg); AR_DEL(gmr_txt); }
void exec_image(char *image) /* Get a Minix image into core, patch it up and execute. */ { int i; struct image_header hdr; char *buf; u32_t vsec, addr, limit, aout, n, totalmem = 0; struct process *procp; /* Process under construction. */ long a_text, a_data, a_bss, a_stack; int banner= 0; long processor= a2l(b_value("processor")); u16_t kmagic, mode; char *console; char params[SECTOR_SIZE]; extern char *sbrk(int); char *verb; /* The stack is pretty deep here, so check if heap and stack collide. */ (void) sbrk(0); if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil) verboseboot = a2l(verb); printf("\nLoading "); pretty_image(image); printf(".\n"); vsec= 0; /* Load this sector from image next. */ addr= mem[0].base; /* Into this memory block. */ limit= mem[0].base + mem[0].size; if (limit > caddr) limit= caddr; /* Allocate and clear the area where the headers will be placed. */ aout = (limit -= PROCESS_MAX * A_MINHDR); /* Clear the area where the headers will be placed. */ raw_clear(aout, PROCESS_MAX * A_MINHDR); /* Read the many different processes: */ for (i= 0; vsec < image_size; i++) { u32_t startaddr; startaddr = addr; if (i == PROCESS_MAX) { printf("There are more then %d programs in %s\n", PROCESS_MAX, image); errno= 0; return; } procp= &process[i]; /* Read header. */ DEBUGEXTRA(("Reading header... ")); for (;;) { if ((buf= get_sector(vsec++)) == nil) return; memcpy(&hdr, buf, sizeof(hdr)); if (BADMAG(hdr.process)) { errno= ENOEXEC; return; } /* Check the optional label on the process. */ if (selected(hdr.name)) break; /* Bad label, skip this process. */ vsec+= proc_size(&hdr); } DEBUGEXTRA(("done\n")); /* Sanity check: an 8086 can't run a 386 kernel. */ if (hdr.process.a_cpu == A_I80386 && processor < 386) { printf("You can't run a 386 kernel on this 80%ld\n", processor); errno= 0; return; } /* Get the click shift from the kernel text segment. */ if (i == KERNEL_IDX) { if (!get_clickshift(vsec, &hdr)) return; addr= align(addr, click_size); /* big kernels must be loaded into extended memory */ if (k_flags & K_KHIGH) { addr= mem[1].base; limit= mem[1].base + mem[1].size; } } /* Save a copy of the header for the kernel, with a_syms * misused as the address where the process is loaded at. */ DEBUGEXTRA(("raw_copy(0x%x, 0x%lx, 0x%x)... ", aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR)); hdr.process.a_syms= addr; raw_copy(aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR); DEBUGEXTRA(("done\n")); if (!banner) { DEBUGBASIC((" cs ds text data bss")); if (k_flags & K_CHMEM) DEBUGBASIC((" stack")); DEBUGBASIC(("\n")); banner= 1; } /* Segment sizes. */ DEBUGEXTRA(("a_text=0x%lx; a_data=0x%lx; a_bss=0x%lx; a_flags=0x%x)\n", hdr.process.a_text, hdr.process.a_data, hdr.process.a_bss, hdr.process.a_flags)); a_text= hdr.process.a_text; a_data= hdr.process.a_data; a_bss= hdr.process.a_bss; if (k_flags & K_CHMEM) { a_stack= hdr.process.a_total - a_data - a_bss; if (!(hdr.process.a_flags & A_SEP)) a_stack-= a_text; } else { a_stack= 0; } /* Collect info about the process to be. */ procp->cs= addr; /* Process may be page aligned so that the text segment contains * the header, or have an unmapped zero page against vaxisms. */ procp->entry= hdr.process.a_entry; if (hdr.process.a_flags & A_PAL) a_text+= hdr.process.a_hdrlen; if (hdr.process.a_flags & A_UZP) procp->cs-= click_size; /* Separate I&D: two segments. Common I&D: only one. */ if (hdr.process.a_flags & A_SEP) { /* Read the text segment. */ DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, a_text, addr, limit)); if (!get_segment(&vsec, &a_text, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx a_text=0x%lx " "addr=0x%lx\n", vsec, a_text, addr)); /* The data segment follows. */ procp->ds= addr; if (hdr.process.a_flags & A_UZP) procp->ds-= click_size; procp->data= addr; } else { /* Add text to data to form one segment. */ procp->data= addr + a_text; procp->ds= procp->cs; a_data+= a_text; } /* Read the data segment. */ DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, a_data, addr, limit)); if (!get_segment(&vsec, &a_data, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx a_data=0x%lx " "addr=0x%lx\n", vsec, a_data, addr)); /* Make space for bss and stack unless... */ if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0; DEBUGBASIC(("%07lx %07lx %8ld %8ld %8ld", procp->cs, procp->ds, hdr.process.a_text, hdr.process.a_data, hdr.process.a_bss)); if (k_flags & K_CHMEM) DEBUGBASIC((" %8ld", a_stack)); /* Note that a_data may be negative now, but we can look at it * as -a_data bss bytes. */ /* Compute the number of bss clicks left. */ a_bss+= a_data; n= align(a_bss, click_size); a_bss-= n; /* Zero out bss. */ DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit)); if (addr + n > limit) { errno= ENOMEM; return; } raw_clear(addr, n); DEBUGEXTRA(("done\n")); addr+= n; /* And the number of stack clicks. */ a_stack+= a_bss; n= align(a_stack, click_size); a_stack-= n; /* Add space for the stack. */ addr+= n; /* Process endpoint. */ procp->end= addr; if (verboseboot >= VERBOSEBOOT_BASIC) printf(" %s\n", hdr.name); else { u32_t mem; mem = addr-startaddr; printf("%s ", hdr.name); totalmem += mem; } if (i == 0 && (k_flags & (K_HIGH | K_KHIGH)) == K_HIGH) { /* Load the rest in extended memory. */ addr= mem[1].base; limit= mem[1].base + mem[1].size; } } if (verboseboot < VERBOSEBOOT_BASIC) printf("(%dk)\n", totalmem/1024); if ((n_procs= i) == 0) { printf("There are no programs in %s\n", image); errno= 0; return; } /* Check the kernel magic number. */ raw_copy(mon2abs(&kmagic), process[KERNEL_IDX].data + MAGIC_OFF, sizeof(kmagic)); if (kmagic != KERNEL_D_MAGIC) { printf("Kernel magic number is incorrect (0x%x@0x%lx)\n", kmagic, process[KERNEL_IDX].data + MAGIC_OFF); errno= 0; return; } /* Patch sizes, etc. into kernel data. */ DEBUGEXTRA(("patch_sizes()... ")); patch_sizes(); DEBUGEXTRA(("done\n")); #if !DOS if (!(k_flags & K_MEML)) { /* Copy the a.out headers to the old place. */ raw_copy(HEADERPOS, aout, PROCESS_MAX * A_MINHDR); } #endif /* Run the trailer function just before starting Minix. */ DEBUGEXTRA(("run_trailer()... ")); if (!run_trailer()) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Translate the boot parameters to what Minix likes best. */ DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params))); if (!params2params(params, sizeof(params))) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Set the video to the required mode. */ if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) { mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE : MONO_MODE; } DEBUGEXTRA(("set_mode(%d)... ", mode)); set_mode(mode); DEBUGEXTRA(("done\n")); /* Close the disk. */ DEBUGEXTRA(("dev_close()... ")); (void) dev_close(); DEBUGEXTRA(("done\n")); /* Minix. */ DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n", process[KERNEL_IDX].entry, process[KERNEL_IDX].cs, process[KERNEL_IDX].ds, params, sizeof(params), aout)); minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs, process[KERNEL_IDX].ds, params, sizeof(params), aout); if (!(k_flags & K_BRET)) { extern u32_t reboot_code; raw_copy(mon2abs(params), reboot_code, sizeof(params)); } parse_code(params); /* Return from Minix. Things may have changed, so assume nothing. */ fsok= -1; errno= 0; /* Read leftover character, if any. */ scan_keyboard(); /* Restore screen contents. */ restore_screen(); }
void exec_mb(char *kernel, char* modules) /* Get a Minix image into core, patch it up and execute. */ { int i; static char hdr[SECTOR_SIZE]; char *buf; u32_t vsec, addr, limit, n, totalmem = 0; u16_t kmagic, mode; char *console; char params[SECTOR_SIZE]; extern char *sbrk(int); char *verb; u32_t text_vaddr, text_paddr, text_filebytes, text_membytes; u32_t data_vaddr, data_paddr, data_filebytes, data_membytes; u32_t pc; u32_t text_offset, data_offset; i32_t segsize; int r; u32_t cs, ds; char *modstring, *mod; multiboot_info_t *mbinfo; multiboot_module_t *mbmodinfo; u32_t mbinfo_size, mbmodinfo_size; char *memvar; memory *mp; u32_t mod_cmdline_start, kernel_cmdline_start; u32_t modstringlen; int modnr; /* The stack is pretty deep here, so check if heap and stack collide. */ (void) sbrk(0); if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil) verboseboot = a2l(verb); printf("\nLoading %s\n", kernel); vsec= 0; /* Load this sector from kernel next. */ addr= mem[0].base; /* Into this memory block. */ limit= mem[0].base + mem[0].size; if (limit > caddr) limit= caddr; /* set click size for get_segment */ click_size = PAGE_SIZE; k_flags = K_KHIGH|K_BRET|K_MEML|K_INT86|K_RET|K_HDR |K_HIGH|K_CHMEM|K_I386; /* big kernels must be loaded into extended memory */ addr= mem[1].base; limit= mem[1].base + mem[1].size; /* Get first sector */ DEBUGEXTRA(("get_sector\n")); if ((buf= get_sector(vsec++)) == nil) { DEBUGEXTRA(("get_sector failed\n")); return; } memcpy(hdr, buf, SECTOR_SIZE); /* Get ELF header */ DEBUGEXTRA(("read_header_elf\n")); r = read_header_elf(hdr, &text_vaddr, &text_paddr, &text_filebytes, &text_membytes, &data_vaddr, &data_paddr, &data_filebytes, &data_membytes, &pc, &text_offset, &data_offset); if (r < 0) { errno= ENOEXEC; return; } /* Read the text segment. */ addr = text_paddr; segsize = (i32_t) text_filebytes; vsec = text_offset / SECTOR_SIZE; DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, segsize, addr, limit)); if (!get_segment(&vsec, &segsize, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " "addr=0x%lx\n", vsec, segsize, addr)); /* Read the data segment. */ addr = data_paddr; segsize = (i32_t) data_filebytes; vsec = data_offset / SECTOR_SIZE; DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, segsize, addr, limit)); if (!get_segment(&vsec, &segsize, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " "addr=0x%lx\n", vsec, segsize, addr)); n = data_membytes - align(data_filebytes, click_size); /* Zero out bss. */ DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit)); if (addr + n > limit) { errno= ENOMEM; return; } raw_clear(addr, n); DEBUGEXTRA(("done\n")); addr+= n; /* Check the kernel magic number. */ raw_copy(mon2abs(&kmagic), data_paddr + MAGIC_OFF, sizeof(kmagic)); if (kmagic != KERNEL_D_MAGIC) { printf("Kernel magic number is incorrect (0x%x@0x%lx)\n", kmagic, data_paddr + MAGIC_OFF); errno= 0; return; } /* Translate the boot parameters to what Minix likes best. */ DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params))); if (!params2params(params, sizeof(params))) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Create multiboot info struct */ mbinfo = malloc(sizeof(multiboot_info_t)); if (mbinfo == nil) { errno= ENOMEM; return; } memset(mbinfo, 0, sizeof(multiboot_info_t)); /* Module info structs start where kernel ends */ mbinfo->mods_addr = addr; modstring = strdup(modules); if (modstring == nil) {errno = ENOMEM; return; } modstringlen = strlen(modules); mbinfo->mods_count = split_module_list(modules); mbmodinfo_size = sizeof(multiboot_module_t) * mbinfo->mods_count; mbmodinfo = malloc(mbmodinfo_size); if (mbmodinfo == nil) { errno= ENOMEM; return; } addr+= mbmodinfo_size; addr= align(addr, click_size); mod_cmdline_start = mbinfo->mods_addr + sizeof(multiboot_module_t) * mbinfo->mods_count; raw_copy(mod_cmdline_start, mon2abs(modules), modstringlen+1); mbmodinfo[0].cmdline = mod_cmdline_start; modnr = 1; for (i= 0; i < modstringlen; ++i) { if (modules[i] == '\0') { mbmodinfo[modnr].cmdline = mod_cmdline_start + i + 1; ++modnr; } } kernel_cmdline_start = mod_cmdline_start + modstringlen + 1; mbinfo->cmdline = kernel_cmdline_start; raw_copy(kernel_cmdline_start, mon2abs(kernel), strlen(kernel)+1); mbinfo->flags = MULTIBOOT_INFO_MODS|MULTIBOOT_INFO_CMDLINE| MULTIBOOT_INFO_BOOTDEV|MULTIBOOT_INFO_MEMORY; mbinfo->boot_device = mbdev; mbinfo->mem_lower = mem[0].size/1024; mbinfo->mem_upper = mem[1].size/1024; for (i = 0, mod = strtok(modstring, " "); mod != nil; mod = strtok(nil, " "), i++) { mod = select_image(mod); if (mod == nil) {errno = 0; return; } mbmodinfo[i].mod_start = addr; mbmodinfo[i].mod_end = addr + image_bytes; mbmodinfo[i].pad = 0; segsize= image_bytes; vsec= 0; DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", vsec, segsize, addr, limit)); if (!get_segment(&vsec, &segsize, &addr, limit)) return; DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx " "addr=0x%lx\n", vsec, segsize, addr)); addr+= segsize; addr= align(addr, click_size); } free(modstring); DEBUGEXTRA(("modinfo raw_copy: dst 0x%lx src 0x%lx sz 0x%lx\n", mbinfo->mods_addr, mon2abs(mbmodinfo), mbmodinfo_size)); raw_copy(mbinfo->mods_addr, mon2abs(mbmodinfo), mbmodinfo_size); free(mbmodinfo); raw_copy(MULTIBOOT_INFO_ADDR, mon2abs(mbinfo), sizeof(multiboot_info_t)); free(mbinfo); /* Run the trailer function just before starting Minix. */ DEBUGEXTRA(("run_trailer()... ")); if (!run_trailer()) { errno= 0; return; } DEBUGEXTRA(("done\n")); /* Set the video to the required mode. */ if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) { mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE : MONO_MODE; } DEBUGEXTRA(("set_mode(%d)... ", mode)); set_mode(mode); DEBUGEXTRA(("done\n")); /* Close the disk. */ DEBUGEXTRA(("dev_close()... ")); (void) dev_close(); DEBUGEXTRA(("done\n")); /* Minix. */ cs = ds = text_paddr; DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n", pc, cs, ds, params, sizeof(params), 0)); minix(pc, cs, ds, params, sizeof(params), 0); if (!(k_flags & K_BRET)) { extern u32_t reboot_code; raw_copy(mon2abs(params), reboot_code, sizeof(params)); } parse_code(params); /* Return from Minix. Things may have changed, so assume nothing. */ fsok= -1; errno= 0; /* Read leftover character, if any. */ scan_keyboard(); /* Restore screen contents. */ restore_screen(); }