diff options
Diffstat (limited to 'com32/lib/syslinux')
-rw-r--r-- | com32/lib/syslinux/disk.c | 534 | ||||
-rw-r--r-- | com32/lib/syslinux/dump_mmap.c | 12 | ||||
-rw-r--r-- | com32/lib/syslinux/dump_movelist.c | 9 | ||||
-rw-r--r-- | com32/lib/syslinux/load_linux.c | 72 | ||||
-rw-r--r-- | com32/lib/syslinux/movebits.c | 42 | ||||
-rw-r--r-- | com32/lib/syslinux/setup_data.c | 47 | ||||
-rw-r--r-- | com32/lib/syslinux/shuffle.c | 18 | ||||
-rw-r--r-- | com32/lib/syslinux/zonelist.c | 24 |
8 files changed, 662 insertions, 96 deletions
diff --git a/com32/lib/syslinux/disk.c b/com32/lib/syslinux/disk.c new file mode 100644 index 00000000..d6409af6 --- /dev/null +++ b/com32/lib/syslinux/disk.c @@ -0,0 +1,534 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin + * Copyright (C) 2010 Shao Miller + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/** + * @file disk.c + * + * Deal with disks and partitions + */ + +#include <dprintf.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslinux/disk.h> + +/** + * Call int 13h, but with retry on failure. Especially floppies need this. + * + * @v inreg CPU register settings upon INT call + * @v outreg CPU register settings returned by INT call + * @ret (int) 0 upon success, -1 upon failure + */ +int disk_int13_retry(const com32sys_t * inreg, com32sys_t * outreg) +{ + int retry = 6; /* Number of retries */ + com32sys_t tmpregs; + + if (!outreg) + outreg = &tmpregs; + + while (retry--) { + __intcall(0x13, inreg, outreg); + if (!(outreg->eflags.l & EFLAGS_CF)) + return 0; /* CF=0, OK */ + } + + return -1; /* Error */ +} + +/** + * Query disk parameters and EBIOS availability for a particular disk. + * + * @v disk The INT 0x13 disk drive number to process + * @v diskinfo The structure to save the queried params to + * @ret (int) 0 upon success, -1 upon failure + */ +int disk_get_params(int disk, struct disk_info *const diskinfo) +{ + static com32sys_t inreg, outreg; + struct disk_ebios_eparam *eparam = __com32.cs_bounce; + + memset(diskinfo, 0, sizeof *diskinfo); + diskinfo->disk = disk; + diskinfo->bps = SECTOR; + + /* Get EBIOS support */ + memset(&inreg, 0, sizeof inreg); + inreg.eax.b[1] = 0x41; + inreg.ebx.w[0] = 0x55aa; + inreg.edx.b[0] = disk; + inreg.eflags.b[0] = 0x3; /* CF set */ + + __intcall(0x13, &inreg, &outreg); + + if (!(outreg.eflags.l & EFLAGS_CF) && + outreg.ebx.w[0] == 0xaa55 && (outreg.ecx.b[0] & 1)) { + diskinfo->ebios = 1; + } + + /* Get extended disk parameters if ebios == 1 */ + if (diskinfo->ebios) { + memset(&inreg, 0, sizeof inreg); + inreg.eax.b[1] = 0x48; + inreg.edx.b[0] = disk; + inreg.esi.w[0] = OFFS(eparam); + inreg.ds = SEG(eparam); + + memset(eparam, 0, sizeof *eparam); + eparam->len = sizeof *eparam; + + __intcall(0x13, &inreg, &outreg); + + if (!(outreg.eflags.l & EFLAGS_CF)) { + diskinfo->lbacnt = eparam->lbacnt; + if (eparam->bps) + diskinfo->bps = eparam->bps; + /* + * don't think about using geometry data returned by + * 48h, as it can differ from 08h a lot ... + */ + } + } + /* + * Get disk parameters the old way - really only useful for hard + * disks, but if we have a partitioned floppy it's actually our best + * chance... + */ + memset(&inreg, 0, sizeof inreg); + inreg.eax.b[1] = 0x08; + inreg.edx.b[0] = disk; + + __intcall(0x13, &inreg, &outreg); + + if (outreg.eflags.l & EFLAGS_CF) + return diskinfo->ebios ? 0 : -1; + + diskinfo->spt = 0x3f & outreg.ecx.b[0]; + diskinfo->head = 1 + outreg.edx.b[1]; + diskinfo->cyl = 1 + (outreg.ecx.b[1] | ((outreg.ecx.b[0] & 0xc0u) << 2)); + + if (diskinfo->spt) + diskinfo->cbios = 1; /* Valid geometry */ + else { + diskinfo->head = 1; + diskinfo->spt = 1; + diskinfo->cyl = 1; + } + + if (!diskinfo->lbacnt) + diskinfo->lbacnt = diskinfo->cyl * diskinfo->head * diskinfo->spt; + + return 0; +} + +/** + * Get disk block(s) and return a malloc'd buffer. + * + * @v diskinfo The disk drive to read from + * @v lba The logical block address to begin reading at + * @v count The number of sectors to read + * @ret data An allocated buffer with the read data + * + * Uses the disk number and information from diskinfo. Read count sectors + * from drive, starting at lba. Return a new buffer, or NULL upon failure. + */ +void *disk_read_sectors(const struct disk_info *const diskinfo, uint64_t lba, + uint8_t count) +{ + com32sys_t inreg; + struct disk_ebios_dapa *dapa = __com32.cs_bounce; + void *buf = (char *)__com32.cs_bounce + diskinfo->bps; + void *data; + uint32_t maxcnt; + + maxcnt = (__com32.cs_bounce_size - diskinfo->bps) / diskinfo->bps; + if (!count || count > maxcnt || lba + count > diskinfo->lbacnt) + return NULL; + + memset(&inreg, 0, sizeof inreg); + + if (diskinfo->ebios) { + dapa->len = sizeof(*dapa); + dapa->count = count; + dapa->off = OFFS(buf); + dapa->seg = SEG(buf); + dapa->lba = lba; + + inreg.esi.w[0] = OFFS(dapa); + inreg.ds = SEG(dapa); + inreg.edx.b[0] = diskinfo->disk; + inreg.eax.b[1] = 0x42; /* Extended read */ + } else { + unsigned int c, h, s, t; + /* + * if we passed lba + count check and we get here, that means that + * lbacnt was calculated from chs geometry (or faked from 1/1/1), thus + * 32bits are perfectly enough and lbacnt corresponds to cylinder + * boundary + */ + s = lba % diskinfo->spt; + t = lba / diskinfo->spt; + h = t % diskinfo->head; + c = t / diskinfo->head; + + inreg.eax.b[0] = count; + inreg.eax.b[1] = 0x02; /* Read */ + inreg.ecx.b[1] = c; + inreg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1); + inreg.edx.b[1] = h; + inreg.edx.b[0] = diskinfo->disk; + inreg.ebx.w[0] = OFFS(buf); + inreg.es = SEG(buf); + } + + if (disk_int13_retry(&inreg, NULL)) + return NULL; + + data = malloc(count * diskinfo->bps); + if (data) + memcpy(data, buf, count * diskinfo->bps); + return data; +} + +/** + * Write disk block(s). + * + * @v diskinfo The disk drive to write to + * @v lba The logical block address to begin writing at + * @v data The data to write + * @v count The number of sectors to write + * @ret (int) 0 upon success, -1 upon failure + * + * Uses the disk number and information from diskinfo. + * Write sector(s) to a disk drive, starting at lba. + */ +int disk_write_sectors(const struct disk_info *const diskinfo, uint64_t lba, + const void *data, uint8_t count) +{ + com32sys_t inreg; + struct disk_ebios_dapa *dapa = __com32.cs_bounce; + void *buf = (char *)__com32.cs_bounce + diskinfo->bps; + uint32_t maxcnt; + + maxcnt = (__com32.cs_bounce_size - diskinfo->bps) / diskinfo->bps; + if (!count || count > maxcnt || lba + count > diskinfo->lbacnt) + return -1; + + memcpy(buf, data, count * diskinfo->bps); + memset(&inreg, 0, sizeof inreg); + + if (diskinfo->ebios) { + dapa->len = sizeof(*dapa); + dapa->count = count; + dapa->off = OFFS(buf); + dapa->seg = SEG(buf); + dapa->lba = lba; + + inreg.esi.w[0] = OFFS(dapa); + inreg.ds = SEG(dapa); + inreg.edx.b[0] = diskinfo->disk; + inreg.eax.b[1] = 0x43; /* Extended write */ + } else { + unsigned int c, h, s, t; + /* + * if we passed lba + count check and we get here, that means that + * lbacnt was calculated from chs geometry (or faked from 1/1/1), thus + * 32bits are perfectly enough and lbacnt corresponds to cylinder + * boundary + */ + s = lba % diskinfo->spt; + t = lba / diskinfo->spt; + h = t % diskinfo->head; + c = t / diskinfo->head; + + inreg.eax.b[0] = count; + inreg.eax.b[1] = 0x03; /* Write */ + inreg.ecx.b[1] = c; + inreg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1); + inreg.edx.b[1] = h; + inreg.edx.b[0] = diskinfo->disk; + inreg.ebx.w[0] = OFFS(buf); + inreg.es = SEG(buf); + } + + if (disk_int13_retry(&inreg, NULL)) + return -1; + + return 0; /* ok */ +} + +/** + * Write disk blocks and verify they were written. + * + * @v diskinfo The disk drive to write to + * @v lba The logical block address to begin writing at + * @v buf The data to write + * @v count The number of sectors to write + * @ret rv 0 upon success, -1 upon failure + * + * Uses the disk number and information from diskinfo. + * Writes sectors to a disk drive starting at lba, then reads them back + * to verify they were written correctly. + */ +int disk_write_verify_sectors(const struct disk_info *const diskinfo, + uint64_t lba, const void *buf, uint8_t count) +{ + char *rb; + int rv; + + rv = disk_write_sectors(diskinfo, lba, buf, count); + if (rv) + return rv; /* Write failure */ + rb = disk_read_sectors(diskinfo, lba, count); + if (!rb) + return -1; /* Readback failure */ + rv = memcmp(buf, rb, count * diskinfo->bps); + free(rb); + return rv ? -1 : 0; +} + +/** + * Dump info about a DOS partition entry + * + * @v part The 16-byte partition entry to examine + */ +void disk_dos_part_dump(const struct disk_dos_part_entry *const part) +{ + (void)part; + dprintf("Partition status _____ : 0x%.2x\n" + "Partition CHS start\n" + " Cylinder ___________ : 0x%.4x (%u)\n" + " Head _______________ : 0x%.2x (%u)\n" + " Sector _____________ : 0x%.2x (%u)\n" + "Partition type _______ : 0x%.2x\n" + "Partition CHS end\n" + " Cylinder ___________ : 0x%.4x (%u)\n" + " Head _______________ : 0x%.2x (%u)\n" + " Sector _____________ : 0x%.2x (%u)\n" + "Partition LBA start __ : 0x%.8x (%u)\n" + "Partition LBA count __ : 0x%.8x (%u)\n" + "-------------------------------\n", + part->active_flag, + chs_cylinder(part->start), + chs_cylinder(part->start), + chs_head(part->start), + chs_head(part->start), + chs_sector(part->start), + chs_sector(part->start), + part->ostype, + chs_cylinder(part->end), + chs_cylinder(part->end), + chs_head(part->end), + chs_head(part->end), + chs_sector(part->end), + chs_sector(part->end), + part->start_lba, part->start_lba, part->length, part->length); +} + +/* Trivial error message output */ +static inline void error(const char *msg) +{ + fputs(msg, stderr); +} + +/** + * This walk-map effectively reverses the little-endian + * portions of a GPT disk/partition GUID for a string representation. + * There might be a better header for this... + */ +static const char guid_le_walk_map[] = { + 3, -1, -1, -1, 0, + 5, -1, 0, + 3, -1, 0, + 2, 1, 0, + 1, 1, 1, 1, 1, 1 +}; + +/** + * Fill a buffer with a textual GUID representation. + * + * @v buf Points to a minimum array of 37 chars + * @v id The GUID to represent as text + * + * The buffer must be >= char[37] and will be populated + * with an ASCII NUL C string terminator. + * Example: 11111111-2222-3333-4444-444444444444 + * Endian: LLLLLLLL-LLLL-LLLL-BBBB-BBBBBBBBBBBB + */ +void guid_to_str(char *buf, const struct guid *const id) +{ + unsigned int i = 0; + const char *walker = (const char *)id; + + while (i < sizeof(guid_le_walk_map)) { + walker += guid_le_walk_map[i]; + if (!guid_le_walk_map[i]) + *buf = '-'; + else { + *buf = ((*walker & 0xF0) >> 4) + '0'; + if (*buf > '9') + *buf += 'A' - '9' - 1; + buf++; + *buf = (*walker & 0x0F) + '0'; + if (*buf > '9') + *buf += 'A' - '9' - 1; + } + buf++; + i++; + } + *buf = 0; +} + +/** + * Create a GUID structure from a textual GUID representation. + * + * @v buf Points to a GUID string to parse + * @v id Points to a GUID to be populated + * @ret (int) Returns 0 upon success, -1 upon failure + * + * The input buffer must be >= 32 hexadecimal chars and be + * terminated with an ASCII NUL. Returns non-zero on failure. + * Example: 11111111-2222-3333-4444-444444444444 + * Endian: LLLLLLLL-LLLL-LLLL-BBBB-BBBBBBBBBBBB + */ +int str_to_guid(const char *buf, struct guid *const id) +{ + char guid_seq[sizeof(struct guid) * 2]; + unsigned int i = 0; + char *walker = (char *)id; + + while (*buf && i < sizeof(guid_seq)) { + switch (*buf) { + /* Skip these three characters */ + case '{': + case '}': + case '-': + break; + default: + /* Copy something useful to the temp. sequence */ + if ((*buf >= '0') && (*buf <= '9')) + guid_seq[i] = *buf - '0'; + else if ((*buf >= 'A') && (*buf <= 'F')) + guid_seq[i] = *buf - 'A' + 10; + else if ((*buf >= 'a') && (*buf <= 'f')) + guid_seq[i] = *buf - 'a' + 10; + else { + /* Or not */ + error("Illegal character in GUID!\n"); + return -1; + } + i++; + } + buf++; + } + /* Check for insufficient valid characters */ + if (i < sizeof(guid_seq)) { + error("Too few GUID characters!\n"); + return -1; + } + buf = guid_seq; + i = 0; + while (i < sizeof(guid_le_walk_map)) { + if (!guid_le_walk_map[i]) + i++; + walker += guid_le_walk_map[i]; + *walker = *buf << 4; + buf++; + *walker |= *buf; + buf++; + i++; + } + return 0; +} + +/** + * Display GPT partition details. + * + * @v gpt_part The GPT partition entry to display + */ +void disk_gpt_part_dump(const struct disk_gpt_part_entry *const gpt_part) +{ + unsigned int i; + char guid_text[37]; + + dprintf("----------------------------------\n" + "GPT part. LBA first __ : 0x%.16llx\n" + "GPT part. LBA last ___ : 0x%.16llx\n" + "GPT part. attribs ____ : 0x%.16llx\n" + "GPT part. name _______ : '", + gpt_part->lba_first, gpt_part->lba_last, gpt_part->attribs); + for (i = 0; i < sizeof(gpt_part->name); i++) { + if (gpt_part->name[i]) + dprintf("%c", gpt_part->name[i]); + } + dprintf("'"); + guid_to_str(guid_text, &gpt_part->type); + dprintf("GPT part. type GUID __ : {%s}\n", guid_text); + guid_to_str(guid_text, &gpt_part->uid); + dprintf("GPT part. unique ID __ : {%s}\n", guid_text); +} + +/** + * Display GPT header details. + * + * @v gpt The GPT header to display + */ +void disk_gpt_header_dump(const struct disk_gpt_header *const gpt) +{ + char guid_text[37]; + + printf("GPT sig ______________ : '%8.8s'\n" + "GPT major revision ___ : 0x%.4x\n" + "GPT minor revision ___ : 0x%.4x\n" + "GPT header size ______ : 0x%.8x\n" + "GPT header checksum __ : 0x%.8x\n" + "GPT reserved _________ : '%4.4s'\n" + "GPT LBA current ______ : 0x%.16llx\n" + "GPT LBA alternative __ : 0x%.16llx\n" + "GPT LBA first usable _ : 0x%.16llx\n" + "GPT LBA last usable __ : 0x%.16llx\n" + "GPT LBA part. table __ : 0x%.16llx\n" + "GPT partition count __ : 0x%.8x\n" + "GPT partition size ___ : 0x%.8x\n" + "GPT part. table chksum : 0x%.8x\n", + gpt->sig, + gpt->rev.fields.major, + gpt->rev.fields.minor, + gpt->hdr_size, + gpt->chksum, + gpt->reserved1, + gpt->lba_cur, + gpt->lba_alt, + gpt->lba_first_usable, + gpt->lba_last_usable, + gpt->lba_table, gpt->part_count, gpt->part_size, gpt->table_chksum); + guid_to_str(guid_text, &gpt->disk_guid); + printf("GPT disk GUID ________ : {%s}\n", guid_text); +} diff --git a/com32/lib/syslinux/dump_mmap.c b/com32/lib/syslinux/dump_mmap.c index 3f1e340b..85638cd9 100644 --- a/com32/lib/syslinux/dump_mmap.c +++ b/com32/lib/syslinux/dump_mmap.c @@ -28,20 +28,22 @@ /* * dump_mmap.c * - * Writes a syslinux_memmap out to a specified file. This is - * intended for debugging. + * Writes a syslinux_memmap out to a dprintf. */ #include <stdio.h> +#include <dprintf.h> #include <syslinux/movebits.h> -void syslinux_dump_memmap(FILE * file, struct syslinux_memmap *memmap) +#ifdef DEBUG +void syslinux_dump_memmap(struct syslinux_memmap *memmap) { - fprintf(file, "%10s %10s %10s\n" + dprintf("%10s %10s %10s\n" "--------------------------------\n", "Start", "Length", "Type"); while (memmap->next) { - fprintf(file, "0x%08x 0x%08x %10d\n", memmap->start, + dprintf("0x%08x 0x%08x %10d\n", memmap->start, memmap->next->start - memmap->start, memmap->type); memmap = memmap->next; } } +#endif diff --git a/com32/lib/syslinux/dump_movelist.c b/com32/lib/syslinux/dump_movelist.c index 282d0068..4042ce96 100644 --- a/com32/lib/syslinux/dump_movelist.c +++ b/com32/lib/syslinux/dump_movelist.c @@ -33,14 +33,17 @@ */ #include <stdio.h> +#include <dprintf.h> #include <syslinux/movebits.h> -void syslinux_dump_movelist(FILE * file, struct syslinux_movelist *ml) +#ifdef DEBUG +void syslinux_dump_movelist(struct syslinux_movelist *ml) { - fprintf(file, "%10s %10s %10s\n" + dprintf("%10s %10s %10s\n" "--------------------------------\n", "Dest", "Src", "Length"); while (ml) { - fprintf(file, "0x%08x 0x%08x 0x%08x\n", ml->dst, ml->src, ml->len); + dprintf("0x%08x 0x%08x 0x%08x\n", ml->dst, ml->src, ml->len); ml = ml->next; } } +#endif diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c index c1ce875c..856141f8 100644 --- a/com32/lib/syslinux/load_linux.c +++ b/com32/lib/syslinux/load_linux.c @@ -38,21 +38,13 @@ #include <inttypes.h> #include <string.h> #include <minmax.h> +#include <errno.h> #include <suffix_number.h> #include <syslinux/align.h> #include <syslinux/linux.h> #include <syslinux/bootrm.h> #include <syslinux/movebits.h> - -#ifndef DEBUG -# define DEBUG 0 -#endif -#if DEBUG -# include <stdio.h> -# define dprintf printf -#else -# define dprintf(f, ...) ((void)0) -#endif +#include <dprintf.h> struct linux_header { uint8_t boot_sector_1[0x0020]; @@ -189,13 +181,16 @@ static int map_initramfs(struct syslinux_movelist **fraglist, } int syslinux_boot_linux(void *kernel_buf, size_t kernel_size, - struct initramfs *initramfs, char *cmdline) + struct initramfs *initramfs, + struct setup_data *setup_data, + char *cmdline) { struct linux_header hdr, *whdr; size_t real_mode_size, prot_mode_size; addr_t real_mode_base, prot_mode_base; addr_t irf_size; size_t cmdline_size, cmdline_offset; + struct setup_data *sdp; struct syslinux_rm_regs regs; struct syslinux_movelist *fraglist = NULL; struct syslinux_memmap *mmap = NULL; @@ -318,10 +313,8 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size, if (!mmap || !amap) goto bail; -#if DEBUG dprintf("Initial memory map:\n"); - syslinux_dump_memmap(stdout, mmap); -#endif + syslinux_dump_memmap(mmap); /* If the user has specified a memory limit, mark that as unavailable. Question: should we mark this off-limit in the mmap as well (meaning @@ -460,6 +453,49 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size, } } + if (setup_data) { + uint64_t *prev_ptr = &whdr->setup_data; + + for (sdp = setup_data->next; sdp != setup_data; sdp = sdp->next) { + struct syslinux_memmap *ml; + const addr_t align_mask = 15; /* Header is 16 bytes */ + addr_t best_addr = 0; + size_t size = sdp->hdr.len + sizeof(sdp->hdr); + + if (!sdp->data || !sdp->hdr.len) + continue; + + if (hdr.version < 0x0209) { + /* Setup data not supported */ + errno = ENXIO; /* Kind of arbitrary... */ + goto bail; + } + + for (ml = amap; ml->type != SMT_END; ml = ml->next) { + addr_t adj_start = (ml->start + align_mask) & ~align_mask; + addr_t adj_end = ml->next->start & ~align_mask; + + if (ml->type == SMT_FREE && adj_end - adj_start >= size) + best_addr = (adj_end - size) & ~align_mask; + } + + if (!best_addr) + goto bail; + + *prev_ptr = best_addr; + prev_ptr = &sdp->hdr.next; + + if (syslinux_add_memmap(&amap, best_addr, size, SMT_ALLOC)) + goto bail; + if (syslinux_add_movelist(&fraglist, best_addr, + (addr_t)&sdp->hdr, sizeof sdp->hdr)) + goto bail; + if (syslinux_add_movelist(&fraglist, best_addr + sizeof sdp->hdr, + (addr_t)sdp->data, sdp->hdr.len)) + goto bail; + } + } + /* Set up the registers on entry */ memset(®s, 0, sizeof regs); regs.es = regs.ds = regs.ss = regs.fs = regs.gs = real_mode_base >> 4; @@ -468,16 +504,14 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size, /* Linux is OK with sp = 0 = 64K, but perhaps other things aren't... */ regs.esp.w[0] = min(cmdline_offset, (size_t) 0xfff0); -#if DEBUG dprintf("Final memory map:\n"); - syslinux_dump_memmap(stdout, mmap); + syslinux_dump_memmap(mmap); dprintf("Final available map:\n"); - syslinux_dump_memmap(stdout, amap); + syslinux_dump_memmap(amap); dprintf("Initial movelist:\n"); - syslinux_dump_movelist(stdout, fraglist); -#endif + syslinux_dump_movelist(fraglist); syslinux_shuffle_boot_rm(fraglist, mmap, 0, ®s); diff --git a/com32/lib/syslinux/movebits.c b/com32/lib/syslinux/movebits.c index bd5ce0e8..7a05f3c1 100644 --- a/com32/lib/syslinux/movebits.c +++ b/com32/lib/syslinux/movebits.c @@ -48,21 +48,7 @@ #include <stdbool.h> #include <syslinux/movebits.h> - -#ifndef DEBUG -# ifdef TEST -# define DEBUG 1 -# else -# define DEBUG 0 -# endif -#endif - -#if DEBUG -# include <stdio.h> -# define dprintf printf -#else -# define dprintf(...) ((void)0) -#endif +#include <dprintf.h> static jmp_buf new_movelist_bail; @@ -242,10 +228,8 @@ static void shuffle_dealias(struct syslinux_movelist **fraglist, addr_t ps, pe, xs, xe, delta; bool advance; -#if DEBUG dprintf("Before alias resolution:\n"); - syslinux_dump_movelist(stdout, *fraglist); -#endif + syslinux_dump_movelist(*fraglist); *postcopy = NULL; @@ -316,12 +300,10 @@ restart: ; } -#if DEBUG dprintf("After alias resolution:\n"); - syslinux_dump_movelist(stdout, *fraglist); + syslinux_dump_movelist(*fraglist); dprintf("Post-shuffle copies:\n"); - syslinux_dump_movelist(stdout, *postcopy); -#endif + syslinux_dump_movelist(*postcopy); } /* @@ -449,12 +431,10 @@ nomem: /* As long as there are unprocessed fragments in the chain... */ while ((fp = &frags, f = *fp)) { -#if DEBUG dprintf("Current free list:\n"); - syslinux_dump_memmap(stdout, mmap); + syslinux_dump_memmap(mmap); dprintf("Current frag list:\n"); - syslinux_dump_movelist(stdout, frags); -#endif + syslinux_dump_movelist(frags); /* Scan for fragments which can be discarded without action. */ if (f->src == f->dst) { @@ -692,16 +672,16 @@ int main(int argc, char *argv[]) *fep = NULL; - printf("Input move list:\n"); - syslinux_dump_movelist(stdout, frags); - printf("Input free list:\n"); - syslinux_dump_memmap(stdout, memmap); + dprintf("Input move list:\n"); + syslinux_dump_movelist(frags); + dprintf("Input free list:\n"); + syslinux_dump_memmap(memmap); if (syslinux_compute_movelist(&moves, frags, memmap)) { printf("Failed to compute a move sequence\n"); return 1; } else { - printf("Final move list:\n"); + dprintf("Final move list:\n"); syslinux_dump_movelist(stdout, moves); return 0; } diff --git a/com32/lib/syslinux/setup_data.c b/com32/lib/syslinux/setup_data.c new file mode 100644 index 00000000..a36c5b61 --- /dev/null +++ b/com32/lib/syslinux/setup_data.c @@ -0,0 +1,47 @@ +#include <stdlib.h> +#include <syslinux/linux.h> +#include <syslinux/loadfile.h> + +struct setup_data *setup_data_init(void) +{ + struct setup_data *setup_data; + + setup_data = zalloc(sizeof(*setup_data)); + if (!setup_data) + return NULL; + + setup_data->prev = setup_data->next = setup_data; + return setup_data; +} + +int setup_data_add(struct setup_data *head, uint32_t type, + const void *data, size_t data_len) +{ + struct setup_data *setup_data; + + setup_data = zalloc(sizeof(*setup_data)); + if (!setup_data) + return -1; + + setup_data->data = data; + setup_data->hdr.len = data_len; + setup_data->hdr.type = type; + setup_data->prev = head->prev; + setup_data->next = head; + head->prev->next = setup_data; + head->prev = setup_data; + + return 0; +} + +int setup_data_load(struct setup_data *head, uint32_t type, + const char *filename) +{ + void *data; + size_t len; + + if (loadfile(filename, &data, &len)) + return -1; + + return setup_data_add(head, type, data, len); +} diff --git a/com32/lib/syslinux/shuffle.c b/com32/lib/syslinux/shuffle.c index 54a7e651..e9ee6aad 100644 --- a/com32/lib/syslinux/shuffle.c +++ b/com32/lib/syslinux/shuffle.c @@ -39,26 +39,10 @@ #include <inttypes.h> #include <com32.h> #include <minmax.h> +#include <dprintf.h> #include <syslinux/movebits.h> #include <klibc/compiler.h> -#ifndef DEBUG -# define DEBUG 0 -#endif - -#define dprintf(f, ...) ((void)0) -#define dprintf2(f, ...) ((void)0) - -#if DEBUG -# include <stdio.h> -# undef dprintf -# define dprintf printf -# if DEBUG > 1 -# undef dprintf2 -# define dprintf2 printf -# endif -#endif - struct shuffle_descriptor { uint32_t dst, src, len; }; diff --git a/com32/lib/syslinux/zonelist.c b/com32/lib/syslinux/zonelist.c index b548211f..7034c4be 100644 --- a/com32/lib/syslinux/zonelist.c +++ b/com32/lib/syslinux/zonelist.c @@ -39,21 +39,7 @@ #include <stdlib.h> #include <syslinux/align.h> #include <syslinux/movebits.h> - -#ifndef DEBUG -# ifdef TEST -# define DEBUG 1 -# else -# define DEBUG 0 -# endif -#endif - -#if DEBUG -# include <stdio.h> -# define dprintf printf -#else -# define dprintf(...) ((void)0) -#endif +#include <dprintf.h> /* * Create an empty syslinux_memmap list. @@ -96,10 +82,8 @@ int syslinux_add_memmap(struct syslinux_memmap **list, struct syslinux_memmap *range; enum syslinux_memmap_types oldtype; -#if DEBUG dprintf("Input memmap:\n"); - syslinux_dump_memmap(stdout, *list); -#endif + syslinux_dump_memmap(*list); /* Remove this to make len == 0 mean all of memory */ if (len == 0) @@ -164,10 +148,8 @@ int syslinux_add_memmap(struct syslinux_memmap **list, } } -#if DEBUG dprintf("After adding (%#x,%#x,%d):\n", start, len, type); - syslinux_dump_memmap(stdout, *list); -#endif + syslinux_dump_memmap(*list); return 0; } |