📄 first32.c
字号:
memsize = getdec(p = ip); while (*p >= '0' && *p <= '9') ++p; if (*p == 'G') memsize <<= 30; else if (*p == 'M') memsize <<= 20; else if (*p == 'K') memsize <<= 10; top_of_initrd = memsize; copy_nonws(); } else copy_nonws();}static inline int skipws(void){ int c; while ((c = *ip) != '\0' && isws(c)) ip++; return (c);}/* * The parameters are copied from the input area to the output * area, looking out for keyword=value pairs while doing so. * If a possible keyword is found, indicated by an =, * it is matched against a small list. * If it matches none of the keywords on the list, * the value is copied unchanged. * If it matches a keyword, then the appropriate substitutions * are made. * While doing the substitution, a check is made that the output * pointer doesn't overrun the input pointer. This is the only * place it could happen, as the substitution may be longer than * the original. */static inline void process_params(void){ int i; while (skipws() != '\0') { if ((i = copy_and_match()) >= 0) subst_value(i); else copy_nonws(); *op++ = ' '; } /* There may be a space after the last arg, probably does not matter but this is a reminder */ *op = '\0';}/* * String is not null terminated, count of chars following is in first element * If there are 6 colons, returns char position after 6th colon * Else returns one position after string * which forces the length calculated below to be negative * Length of 7th argument can be calculated by subtracting the * length of the string preceding from the total length. */static inline unsigned char *skip6colons(unsigned char *p){ int len, coloncount; for (len = *p++, coloncount = 6; len > 0 && coloncount > 0; p++, len--) if (*p == ':') coloncount--; return (p + (coloncount > 0));}static void parse_elf_boot_notes( void *notes, union infoblock **rheader, struct bootp_t **rbootp){ unsigned char *note, *end; Elf_Bhdr *bhdr; Elf_Nhdr *hdr; bhdr = notes; if (bhdr->b_signature != ELF_BHDR_MAGIC) { return; } note = ((char *)bhdr) + sizeof(*bhdr); end = ((char *)bhdr) + bhdr->b_size; while (note < end) { unsigned char *n_name, *n_desc, *next; hdr = (Elf_Nhdr *)note; n_name = note + sizeof(*hdr); n_desc = n_name + ((hdr->n_namesz + 3) & ~3); next = n_desc + ((hdr->n_descsz + 3) & ~3); if (next > end) break;#if 0 printf("n_type: %x n_name(%d): n_desc(%d): \n", hdr->n_type, hdr->n_namesz, hdr->n_descsz);#endif if ((hdr->n_namesz == 10) && (memcmp(n_name, "Etherboot", 10) == 0)) { switch(hdr->n_type) { case EB_BOOTP_DATA: *rbootp = *((void **)n_desc); break; case EB_HEADER: *rheader = *((void **)n_desc); break; default: break; } } note = next; }}int first(struct ebinfo *eb, union infoblock *header, struct bootp_t *bootp){ int i; unsigned char *p, *q, *params; struct bootblock *boot; struct setupblock *setup; union { unsigned long l; unsigned char c[4]; } u;#if DEBUG > 1 printf("&eb = %#X\n", &eb);#endif printf(MKNBI_VERSION "/" __FILE__#ifdef FIRST32ELF " (ELF)"#endif " (GPL)\n");#if DEBUG > 1 printf("eb = %#X, header = %#X, bootp = %#X\n", eb, header, bootp);#endif /* Sanity checks */#ifdef FIRST32ELF parse_elf_boot_notes(eb, &header, &bootp); if (header->img.magic != ELF_MAGIC#else if (header->img.magic != TAG_MAGIC#endif || bootp->bp_op != BOOTP_REPLY) quit(); bp = bootp; vendortags = (unsigned char *)bootp->bp_vend; checkvendor(); locate_segs(header); /* Locate boot block */ boot = (struct bootblock *)seg[S_BOOT]->p_paddr; /* Point to word to alter if vga=... specified */ vgamode = &boot->vgamode; /* Locate setup block */ setup = (struct setupblock *)seg[S_SETUP]->p_paddr; /* Adjust loader type byte */ setup->su_type = SU_MY_LOADER_TYPE; /* If setup version >= 0x202, use new command line protocol. This frees setup.S from being tied to 0x90000 */ if (setup->su_version >= 0x202) setup->su_cmd_line_ptr = params = (unsigned char *)seg[S_PARAMS]->p_paddr; else { /* Use old protocol */ /* Adjust boot block pointers to point to command line */ boot->cl_magic = CL_MAGIC; boot->cl_offset = (params = (unsigned char *)seg[S_PARAMS]->p_paddr) - ((unsigned char *)boot); } p = params + (i = strlen(params) + 1); /* Append T129 if present */ q = gettag(RFC1533_VENDOR_MAGIC); /* Check T128 present and correct */ if (*q == 6 && (memcpy(u.c, q + 1, sizeof(u)), u.l == VEND_EB)) { q = gettag(RFC1533_VENDOR_ADDPARM); i = PARAMSIZE - 1 - i; /* +1 for SPACE */ if (i > *q) /* enough space? */ i = *q; q++; if (i > 0) p[-1] = ' '; /* NUL -> space */ while (i-- > 0) *p++ = *q++; *p++ = '\0'; /* position past NUL */ if (*(q = gettag(RFC1533_VENDOR_SELECTION)) == 1 && *(q = gettag(q[1])) > 0) { unsigned char *r = skip6colons(q); /* If we have an argument and enough space, copy it */ if ((i = *q - (r - q) + 1) > 0 && i < PARAMSIZE - 2 - strlen(params)) { /* +2 for SPACE and final NUL */ p[-1] = ' '; while (i-- > 0) { /* escapes: ~b -> \\, ~c -> : */ if (i > 0 && r[0] == '~' && r[1] == 'b') *p++ = '\\', r += 2, --i; else if (i > 0 && r[0] == '~' && r[1] == 'c') *p++ = ':', r += 2, --i; else *p++ = *r++; } *p++ = '\0'; } } } /* Move parameters to end of parameter area, tail first to avoid overwriting */ q = params + PARAMSIZE; /* At least 1 byte is copied, the NUL */ do { *--q = *--p; } while (p != params); ip = q; op = params;#ifdef DEBUG printf("Parameters: %s\n", p);#endif /* mem= param affects top_of_initrd */ process_params(); if (seg[S_RAMDISK] != 0) { unsigned long max; get_memsizes(); max = (setup->su_version >= 0x203) ? setup->ramdisk_max : 0x37FFFFFF; /* compute top of initrd only if user has not overridden it */ if (top_of_initrd == 0) { struct e820entry *e; /* look for highest E820_RAM that is under ramdisk_max strictly speaking we should also check that we have room for the ramdisk in the memory segment */ for (i = 0; i < meminfo.map_count; i++) { e = &meminfo.map[i]; if (e->type == E820_RAM && e->addr < max && (e->addr + e->size) > top_of_initrd) top_of_initrd = e->addr + e->size; } } if (top_of_initrd > max) top_of_initrd = max; /* Round down to next lower 4k boundary */ top_of_initrd &= ~0xFFF; printf("Top of ramdisk is %#X\n", top_of_initrd); if (rdmode == RD_TOP || rdmode == RD_HEXADDR) { long *dp, *sp; sp = (long *)((p = (unsigned char *)seg[S_RAMDISK]->p_paddr) + (i = seg[S_RAMDISK]->p_filesz)); /* * If user specified address, align to next lower * longword boundary */ if (rdmode == RD_HEXADDR) dp = (long *)((rdaddr + i) & ~0x3); else dp = (long *)top_of_initrd; /* Copy to destination by longwords, tail first */ while (sp > (long *)p) *--dp = *--sp; printf("Ramdisk at %#X, size %#X\n", (setup->su_ramdisk_start = (unsigned long)dp), (setup->su_ramdisk_size = i)); } else { /* leave ramdisk as loaded, just report */ printf("Ramdisk at %#X, size %#X\n", (setup->su_ramdisk_start = (unsigned long)seg[S_RAMDISK]->p_paddr), (setup->su_ramdisk_size = seg[S_RAMDISK]->p_filesz)); } }#ifdef DEBUG printf("Ready\n");#endif#if DEBUG > 3 /* Delay so we can read display */ for (i = 0; i < 0x7ffffff; i++) ;#endif xstart((unsigned long)setup); return (0);}#endif /* FIRST32LINUX */#ifdef FIRST32DOSextern void printf(const char *, ...);extern void xstart(unsigned long, union infoblock *, struct bootp_t *);extern void exit(int);struct bootp_t bpcopy;void putchar(int c){ if (c == '\n') putchar('\r'); console_putc(c);}static inline void quit(void){ printf("Bad argument\n"); exit(0);}static void parse_elf_boot_notes( void *notes, union infoblock **rheader, struct bootp_t **rbootp){ unsigned char *note, *end; Elf_Bhdr *bhdr; Elf_Nhdr *hdr; bhdr = notes; if (bhdr->b_signature != ELF_BHDR_MAGIC) { return; } note = ((char *)bhdr) + sizeof(*bhdr); end = ((char *)bhdr) + bhdr->b_size; while (note < end) { unsigned char *n_name, *n_desc, *next; hdr = (Elf_Nhdr *)note; n_name = note + sizeof(*hdr); n_desc = n_name + ((hdr->n_namesz + 3) & ~3); next = n_desc + ((hdr->n_descsz + 3) & ~3); if (next > end) break;#if 0 printf("n_type: %x n_name(%d): n_desc(%d): \n", hdr->n_type, hdr->n_namesz, hdr->n_descsz);#endif if ((hdr->n_namesz == 10) && (memcmp(n_name, "Etherboot", 10) == 0)) { switch(hdr->n_type) { case EB_BOOTP_DATA: *rbootp = *((void **)n_desc); break; case EB_HEADER: *rheader = *((void **)n_desc); break; default: break; } } note = next; }}int first(struct ebinfo *eb, union infoblock *header, struct bootp_t *bootp){#if DEBUG > 1 printf("&eb = %#X\n", &eb);#endif printf(MKNBI_VERSION "/" __FILE__ " (ELF)" " (GPL)\n");#if DEBUG > 1 printf("eb = %#X, header = %#X, bootp = %#X\n", eb, header, bootp);#endif /* Sanity checks */ parse_elf_boot_notes(eb, &header, &bootp); if (header->img.magic != ELF_MAGIC || bootp->bp_op != BOOTP_REPLY) quit(); memcpy(&bpcopy, bootp, sizeof(bpcopy)); xstart(RELOC - 0x1000, header, &bpcopy); return (0);}#endif /* FIRST32DOS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -