示例#1
0
/**
*  Generic resampler. Provided an appropriate filter is designed,
*  this resampler can accommodate any resampling ratio of
*  interpfac/decimfac.
*/
void amxrCResample(int16_t *insamp,	/*<< (i) Ptr to input samples */
		   int16_t *outsamp,	/*<< (o) Ptr to output samples */
		   int16_t numsamp,	/*<< (i) Number of samples to generate */
		   const int16_t *filtcoeff,	/*<< (i) Ptr to filter coefficients */
		   int filtlen,	/*<< (i) Filter length */
		   int interpfac,	/*<< (i) Interpolation factor */
		   int decimfac	/*<< (i) Decimation factor */
    ) {
	int samptoskip;
	int interppos;
	int i, j;
	const int16_t *filt;

	/* Adjust sample pointer to start at the beginning of history
	 * to perform forward traversal filtering
	 */
	insamp = insamp - filtlen + 1;
	interppos = 0;
	for (i = 0; i < numsamp; i++) {
		int16_t *sampptr;
		int64_t sum;
		int32_t satnum;

		filt = &filtcoeff[interppos * filtlen];
		sampptr = insamp;
		sum = 0x08000L;
		for (j = 0; j < filtlen; j++) {
			/* do filter in forward traversal */
			sum += (int32_t)(filt[j]) * (int32_t)(*sampptr++) * 2;
		}

		satnum = saturate32(sum);
		*outsamp = (int16_t)(satnum >> 16);
		outsamp++;

		interppos += decimfac;
		samptoskip = interppos / interpfac;
		interppos %= interpfac;
		insamp += samptoskip;
	}
}
示例#2
0
/* boot linux kernel and initrd */
static int sl_boot_linux(lua_State * L)
{
    const char *kernel = luaL_checkstring(L, 1);
    const char *cmdline = luaL_optstring(L, 2, "");
    char *initrd;
    void *kernel_data, *file_data;
    size_t kernel_len, file_len;
    struct initramfs *initramfs;
    char *newcmdline;
    uint32_t mem_limit = luaL_optint(L, 3, 0);
    uint16_t video_mode = luaL_optint(L, 4, 0);
//  int ret, i;
    int ret;
    char **argv, **argp, *arg, *p;

    ret = __parse_argv(&argv, cmdline);

    newcmdline = malloc(strlen(kernel) + 12);
    if (!newcmdline)
	printf("Mem alloc failed: cmdline\n");

    strcpy(newcmdline, "BOOT_IMAGE=");
    strcpy(newcmdline + strlen(newcmdline), kernel);
    argv[0] = newcmdline;
    argp = argv;

    /* DEBUG
       for (i=0; i<ret; i++)
       printf("%d: %s\n", i, argv[i]);
     */

    newcmdline = make_cmdline(argp);
    if (!newcmdline)
	printf("Creating command line failed!\n");

    /* DEBUG
       printf("Command line: %s\n", newcmdline);
       msleep(1000);
     */

    /* Look for specific command-line arguments we care about */
    if ((arg = find_argument(argp, "mem=")))
	mem_limit = saturate32(suffix_number(arg));

    if ((arg = find_argument(argp, "vga="))) {
	switch (arg[0] | 0x20) {
	case 'a':		/* "ask" */
	    video_mode = 0xfffd;
	    break;
	case 'e':		/* "ext" */
	    video_mode = 0xfffe;
	    break;
	case 'n':		/* "normal" */
	    video_mode = 0xffff;
	    break;
	default:
	    video_mode = strtoul(arg, NULL, 0);
	    break;
	}
    }

    printf("Loading kernel %s...\n", kernel);
    if (loadfile(kernel, &kernel_data, &kernel_len))
	printf("failed!\n");
    else
	printf("ok\n");

    initramfs = initramfs_init();
    if (!initramfs)
	printf("Initializing initrd failed!\n");

    if ((arg = find_argument(argp, "initrd="))) {
	do {
	    p = strchr(arg, ',');
	    if (p)
		*p = '\0';

	    initrd = arg;
	    printf("Loading initrd %s... ", initrd);
	    if (initramfs_load_archive(initramfs, initrd)) {
		printf("failed!\n");
	    }
	    printf("ok\n");

	    if (p)
		*p++ = ',';
	} while ((arg = p));
    }

    if (!loadfile("/testfile1", &file_data, &file_len)) {
	if (initramfs_add_file(initramfs, file_data, file_len, file_len,
			       "/testfile1", 0, 0755))
	    printf("Adding extra file failed\n");
    } else
	printf("Loading extra file failed\n");

    /* DEBUG
       msleep(10000);
     */

    ret = syslinux_boot_linux(kernel_data, kernel_len, initramfs, newcmdline);

    printf("syslinux_boot_linux returned %d\n", ret);

    return 0;
}
示例#3
0
int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
			struct initramfs *initramfs, 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 syslinux_rm_regs regs;
    struct syslinux_movelist *fraglist = NULL;
    struct syslinux_memmap *mmap = NULL;
    struct syslinux_memmap *amap = NULL;
    bool ok;
    uint32_t memlimit = 0;
    uint16_t video_mode = 0;
    const char *arg;

    cmdline_size = strlen(cmdline) + 1;

    if (kernel_size < 2 * 512)
	goto bail;

    /* Look for specific command-line arguments we care about */
    if ((arg = find_argument(cmdline, "mem=")))
	memlimit = saturate32(suffix_number(arg));

    if ((arg = find_argument(cmdline, "vga="))) {
	switch (arg[0] | 0x20) {
	case 'a':		/* "ask" */
	    video_mode = 0xfffd;
	    break;
	case 'e':		/* "ext" */
	    video_mode = 0xfffe;
	    break;
	case 'n':		/* "normal" */
	    video_mode = 0xffff;
	    break;
	case 'c':		/* "current" */
	    video_mode = 0x0f04;
	    break;
	default:
	    video_mode = strtoul(arg, NULL, 0);
	    break;
	}
    }

    /* Copy the header into private storage */
    /* Use whdr to modify the actual kernel header */
    memcpy(&hdr, kernel_buf, sizeof hdr);
    whdr = (struct linux_header *)kernel_buf;

    if (hdr.boot_flag != BOOT_MAGIC)
	goto bail;

    if (hdr.header != LINUX_MAGIC) {
	hdr.version = 0x0100;	/* Very old kernel */
	hdr.loadflags = 0;
    }

    whdr->vid_mode = video_mode;

    if (!hdr.setup_sects)
	hdr.setup_sects = 4;

    if (hdr.version < 0x0203)
	hdr.initrd_addr_max = 0x37ffffff;

    if (!memlimit && memlimit - 1 > hdr.initrd_addr_max)
	memlimit = hdr.initrd_addr_max + 1;	/* Zero for no limit */

    if (hdr.version < 0x0205 || !(hdr.loadflags & LOAD_HIGH))
	hdr.relocatable_kernel = 0;

    if (hdr.version < 0x0206)
	hdr.cmdline_max_len = 256;

    if (cmdline_size > hdr.cmdline_max_len) {
	cmdline_size = hdr.cmdline_max_len;
	cmdline[cmdline_size - 1] = '\0';
    }

    if (hdr.version < 0x0202 || !(hdr.loadflags & 0x01))
	cmdline_offset = (0x9ff0 - cmdline_size) & ~15;
    else
	cmdline_offset = 0x10000;

    real_mode_size = (hdr.setup_sects + 1) << 9;
    real_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x10000 : 0x90000;
    prot_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x100000 : 0x10000;
    prot_mode_size = kernel_size - real_mode_size;

    if (!(hdr.loadflags & LOAD_HIGH) && prot_mode_size > 512 * 1024)
	goto bail;		/* Kernel cannot be loaded low */

    if (initramfs && hdr.version < 0x0200)
	goto bail;		/* initrd/initramfs not supported */

    if (hdr.version >= 0x0200) {
	whdr->type_of_loader = 0x30;	/* SYSLINUX unknown module */
	if (hdr.version >= 0x0201) {
	    whdr->heap_end_ptr = cmdline_offset - 0x0200;
	    whdr->loadflags |= CAN_USE_HEAP;
	}
	if (hdr.version >= 0x0202) {
	    whdr->cmd_line_ptr = real_mode_base + cmdline_offset;
	} else {
	    whdr->old_cmd_line_magic = OLD_CMDLINE_MAGIC;
	    whdr->old_cmd_line_offset = cmdline_offset;
	    /* Be paranoid and round up to a multiple of 16 */
	    whdr->setup_move_size = (cmdline_offset + cmdline_size + 15) & ~15;
	}
    }

    /* Get the memory map */
    mmap = syslinux_memory_map();	/* Memory map for shuffle_boot */
    amap = syslinux_dup_memmap(mmap);	/* Keep track of available memory */
    if (!mmap || !amap)
	goto bail;

#if DEBUG
    dprintf("Initial memory map:\n");
    syslinux_dump_memmap(stdout, mmap);
#endif

    /* 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
       it's unavailable to the boot loader, which probably has already touched
       some of it), or just in the amap? */
    if (memlimit)
	if (syslinux_add_memmap(&amap, memlimit, -memlimit, SMT_RESERVED))
	    goto bail;

    /* Place the kernel in memory */

    /* First, find a suitable place for the protected-mode code */
    if (syslinux_memmap_type(amap, prot_mode_base, prot_mode_size)
	!= SMT_FREE) {
	const struct syslinux_memmap *mp;
	if (!hdr.relocatable_kernel)
	    goto bail;		/* Can't relocate - no hope */

	ok = false;
	for (mp = amap; mp; mp = mp->next) {
	    addr_t start, end;
	    start = mp->start;
	    end = mp->next->start;

	    if (mp->type != SMT_FREE)
		continue;

	    if (end <= prot_mode_base)
		continue;	/* Only relocate upwards */

	    if (start <= prot_mode_base)
		start = prot_mode_base;

	    start = ALIGN_UP(start, hdr.kernel_alignment);
	    if (start >= end)
		continue;

	    /* The 3* here is a total fudge factor... it's supposed to
	       account for the fact that the kernel needs to be decompressed,
	       and then followed by the BSS and BRK regions.  This doesn't,
	       however, account for the fact that the kernel is decompressed
	       into a whole other place, either. */
	    if (end - start >= 3 * prot_mode_size) {
		whdr->code32_start += start - prot_mode_base;
		prot_mode_base = start;
		ok = true;
		break;
	    }
	}

	if (!ok)
	    goto bail;
    }

    /* Real mode code */
    if (syslinux_memmap_type(amap, real_mode_base,
			     cmdline_offset + cmdline_size) != SMT_FREE) {
	const struct syslinux_memmap *mp;

	ok = false;
	for (mp = amap; mp; mp = mp->next) {
	    addr_t start, end;
	    start = mp->start;
	    end = mp->next->start;

	    if (mp->type != SMT_FREE)
		continue;

	    if (start < real_mode_base)
		start = real_mode_base;	/* Lowest address we'll use */
	    if (end > 640 * 1024)
		end = 640 * 1024;

	    start = ALIGN_UP(start, 16);
	    if (start > 0x90000 || start >= end)
		continue;

	    if (end - start >= cmdline_offset + cmdline_size) {
		real_mode_base = start;
		ok = true;
		break;
	    }
	}
    }

    if (syslinux_add_movelist(&fraglist, real_mode_base, (addr_t) kernel_buf,
			      real_mode_size))
	goto bail;
    if (syslinux_add_memmap
	(&amap, real_mode_base, cmdline_offset + cmdline_size, SMT_ALLOC))
	goto bail;

    /* Zero region between real mode code and cmdline */
    if (syslinux_add_memmap(&mmap, real_mode_base + real_mode_size,
			    cmdline_offset - real_mode_size, SMT_ZERO))
	goto bail;

    /* Command line */
    if (syslinux_add_movelist(&fraglist, real_mode_base + cmdline_offset,
			      (addr_t) cmdline, cmdline_size))
	goto bail;

    /* Protected-mode code */
    if (syslinux_add_movelist(&fraglist, prot_mode_base,
			      (addr_t) kernel_buf + real_mode_size,
			      prot_mode_size))
	goto bail;
    if (syslinux_add_memmap(&amap, prot_mode_base, prot_mode_size, SMT_ALLOC))
	goto bail;

    /* Figure out the size of the initramfs, and where to put it.
       We should put it at the highest possible address which is
       <= hdr.initrd_addr_max, which fits the entire initramfs. */

    irf_size = initramfs_size(initramfs);	/* Handles initramfs == NULL */

    if (irf_size) {
	addr_t best_addr = 0;
	struct syslinux_memmap *ml;
	const addr_t align_mask = INITRAMFS_MAX_ALIGN - 1;

	if (irf_size) {
	    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 >= irf_size)
		    best_addr = (adj_end - irf_size) & ~align_mask;
	    }

	    if (!best_addr)
		goto bail;	/* Insufficient memory for initramfs */

	    whdr->ramdisk_image = best_addr;
	    whdr->ramdisk_size = irf_size;

	    if (syslinux_add_memmap(&amap, best_addr, irf_size, SMT_ALLOC))
		goto bail;

	    if (map_initramfs(&fraglist, &mmap, initramfs, best_addr))
		goto bail;
	}
    }

    /* Set up the registers on entry */
    memset(&regs, 0, sizeof regs);
    regs.es = regs.ds = regs.ss = regs.fs = regs.gs = real_mode_base >> 4;
    regs.cs = (real_mode_base >> 4) + 0x20;
    /* regs.ip = 0; */
    /* 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);

    dprintf("Final available map:\n");
    syslinux_dump_memmap(stdout, amap);

    dprintf("Initial movelist:\n");
    syslinux_dump_movelist(stdout, fraglist);
#endif

    syslinux_shuffle_boot_rm(fraglist, mmap, 0, &regs);

bail:
    syslinux_free_movelist(fraglist);
    syslinux_free_memmap(mmap);
    syslinux_free_memmap(amap);
    return -1;
}