Luciano Miguel Ferreira Rocha
2007-Apr-26 19:38 UTC
[syslinux] boot 32 or 64 kernel depending on cpu
Hello, The attached l32or64.c implements a com32 module that boots two different kernels with different initrds depending on whether the cpu has long mode support or not. I stumbled upon two problems while developing it with current git version (last commit 595705ffad4f63cfeb84e9bb1243df03808c2fff). The first was that syslinux_boot_linux didn't work for me. Both the command line and initrd data was garbage. The code I was developing is attached as l32or64_linux.c The seconda was that com32/include/syslinux/boot.h declares syslinux_run_kernel_image, but it isn't defined anywhere, so I went with syslinux_run_command. Regards, Luciano Rocha PS: not gpg-signed because syslinux at zytor.com thinks that's suspicious. -- lfr 0/0 -------------- next part -------------- /* ----------------------------------------------------------------------- * * * Copyright 2007 Luciano Rocha - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * l32or64.c * * Load linux kernel depending on cpu support for long mode (64 bits) */ #include <string.h> #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <console.h> #include <cpuid.h> #include <syslinux/boot.h> int main(int argc, char *argv[]) { const char *kernel, *initrd; char cmdline[1024]; int i; unsigned p; s_cpu cpu; openconsole(&dev_stdcon_r, &dev_stdcon_w); if (argc < 5) { fprintf(stderr, "missing options, usage:\n" " l23or64 <32b kernel> <32b initrd> \\" " <64b kernel> <64b initrd> \\" " [kernel arguments]\n"); return 1; } detect_cpu(&cpu); if (cpu.flags.lm) { initrd = argv[4]; kernel = argv[3]; } else { initrd = argv[2]; kernel = argv[1]; } p = snprintf(cmdline, sizeof cmdline - 1, "%s initrd=%s ", kernel, initrd); for (i = 5; i < argc; i++) { unsigned l = strlen(argv[i]); if ((p + l + 1) >= sizeof cmdline) { fprintf(stderr, "command line exceeds internal " "buffers, trimmed.\n"); break; } memcpy(cmdline + p, argv[i], l); cmdline[p + l] = ' '; p += l + 1; } cmdline[p] = '\0'; syslinux_run_command(cmdline); return 1; } -------------- next part -------------- /* ----------------------------------------------------------------------- * * * Copyright 2007 Luciano Rocha - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* * l32or64.c * * Load linux kernel depending on cpu support for long mode (64 bits) */ #include <string.h> #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <console.h> #include <syslinux/loadfile.h> #include <syslinux/linux.h> #include "cpuid.h" int main(int argc, char *argv[]) { const char *kernel, *initrd; void *kernel_data, *initrd_data; struct initramfs *rd; size_t kernel_len, initrd_len; char cmdline[1024]; uint32_t mem_limit = 0; uint16_t video_mode = 0; int i; unsigned p; char _b[64]; #define pause() (fgets(_b, sizeof _b, stdin)) s_cpu cpu; openconsole(&dev_stdcon_r, &dev_stdcon_w); for (i = 0; i < argc; i++) { printf("argument %d: '%s'\n", i, argv[i]); } pause(); if (argc < 5) { fprintf(stderr, "missing options, usage:\n" " l23or64 <32b kernel> <32b initrd> \\" " <64b kernel> <64b initrd> \\" " [kernel arguments]\n"); return 1; } detect_cpu(&cpu); if (cpu.flags.lm) { initrd = argv[4]; kernel = argv[3]; } else { initrd = argv[2]; kernel = argv[1]; } printf("kernel: %s\ninitrd: %s\n", kernel, initrd); cmdline[0] = '\0'; for (i = 5, p = 0; i < argc; i++) { unsigned l = strlen(argv[i]); if ((p + l + 1) >= sizeof cmdline) { fprintf(stderr, "command line exceeds internal " "buffers, trimmed.\n"); break; } memcpy(cmdline + p, argv[i], l); cmdline[p + l] = ' '; p += l + 1; /* check for mem= or video= */ if (!strncmp(argv[i], "mem=", 4)) { char *suf; mem_limit = strtoul(argv[i] + 4, &suf, 0); switch (toupper(*suf)) { case 'g': mem_limit <<= 10; case 'm': mem_limit <<= 10; case 'k': mem_limit <<= 10; } } else if (!strncmp(argv[i], "video=", 6)) { video_mode = strtoul(argv[i] + 6, NULL, 0); } } cmdline[p] = '\0'; printf("cmdline: %s\n", cmdline); pause(); i = loadfile(kernel, &kernel_data, &kernel_len); printf("load %s: %d (%d)\n", kernel, i, kernel_len); if (i) { fprintf(stderr, "kernel %s failed to load\n", kernel); return 1; } if (!(rd = initramfs_init())) { fprintf(stderr, "couldn't initialize initramfs\n"); return 1; } i = loadfile(initrd, &initrd_data, &initrd_len); printf("load %s: %d (%d)\n", initrd, i, initrd_len); if (i) { fprintf(stderr, "initrd %s failed to load\n", initrd); return 1; } if (initramfs_add_data(rd, initrd_data, initrd_len, initrd_len, 4)) { fprintf(stderr, "couldn't add initrd data\n"); return 1; } printf("initramfs_len: %d\n", rd->len); printf("initramfs_len: %d\n", rd->data_len); printf("initramfs_len: %d\n", rd->next->len); printf("initramfs_len: %d\n", rd->next->data_len); pause(); syslinux_boot_linux(kernel_data, kernel_len, rd, cmdline, video_mode, mem_limit); return 0; } -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://www.zytor.com/pipermail/syslinux/attachments/20070426/4f7892ab/attachment.sig>
Luciano Miguel Ferreira Rocha
2007-Apr-26 19:46 UTC
[syslinux] boot 32 or 64 kernel depending on cpu
On Thu, Apr 26, 2007 at 08:38:04PM +0100, Luciano Miguel Ferreira Rocha wrote:> PS: not gpg-signed because syslinux at zytor.com thinks that's suspicious.Oops, force of habit, but this time it didn't go to the moderator (or he was fast), so this is good news for me. -- lfr 0/0
Luciano Miguel Ferreira Rocha wrote:> > The first was that syslinux_boot_linux didn't work for me. Both the > command line and initrd data was garbage. The code I was developing is > attached as l32or64_linux.c >When you say garbage, are you talking about it being correct before booting and then it being crap, or is it crap only after booting the kernel. A lot of your code there is just plain wrong. I suggest using more of the code from com32/modules/linux.c including the command-line parsing and using initramfs_load_archive(). -hpa
Reasonably Related Threads
- CentOS 5 single DVD for i386 and x86_64
- [PATCH 0/1] EFI image booting capabilities
- shoudl I use apply, sapply, etc instead of a "for loop"?
- [PATCH][git-pull] lua: make kernel and initrd progress output match in sl_boot_linux
- [PATCH][git-pull] lua: make kernel and initrd progress output match in sl_boot_linux