kexec support for plan9 continued

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



good day.

previous mail seems to be stuck in moderation for some
reason. can someone please check?

anyway, theres some progress.

i'v changed the 9front kernel to cope with missing acpi
table pointer and use the memory map now looking for the
RSD PTR structure in the ACPI reserved area.

the linux framebuffer stuff appears to be an issue with
the vmware framebuffer driver only. if i force it to use
vesa i get a linear framebuffer with the physical address
of it just fine. wrote a tool that generates the required
boot parameter for plan9. still would be nice to have the
framebuffer mode info in kexec itself for multiboot no?
given that it already tries to do vga state manegement
for x86 (--reset-vga).

attached is the plan9 support code.

so is there interest in supporting this upstream?

--
cinap
/*
 * kexec: Linux boots Plan9
 *
 * 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 (version 2 of the License).
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <getopt.h>
#include <elf.h>
#include "../../kexec.h"
#include "../../kexec-elf.h"
#include "../../kexec-elf-boot.h"
#include "kexec-x86.h"
#include <arch/options.h>

#define PGROUND(x)	(((x)+0xfff) & ~0xfff)
#define CONFADDR	0x1200
#define BOOTLINELEN	64

static char confbuf[0x1000];
static char *conf = confbuf + (CONFADDR & 0xfff) + BOOTLINELEN;
static char *confend = &confbuf[sizeof(confbuf)];

#define HDR_MAGIC	0x00008000		/* header expansion */
#define	_MAGIC(f, b)	((f)|((((4*(b))+0)*(b))+7))
#define	I_MAGIC		_MAGIC(0, 11)		/* intel 386 */
#define	S_MAGIC		_MAGIC(HDR_MAGIC, 26)	/* amd64 */

struct aouthdr
{
	uint32_t	magic;		/* magic number */
	uint32_t	text;	 	/* size of text segment */
	uint32_t	data;	 	/* size of initialized data */
	uint32_t	bss;	  	/* size of uninitialized data */
	uint32_t	syms;	 	/* size of symbol table */
	uint32_t	entry;	 	/* entry point */
	uint32_t	spsz;		/* size of pc/sp offset table */
	uint32_t	pcsz;		/* size of pc/line number table */
};

static uint32_t
l2be(uint32_t l)
{
	unsigned char *cp;

	cp = (unsigned char*)&l;
	return cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
}

int plan9_x86_probe(const char *buf, off_t len)
{
	struct aouthdr hdr;
	uint32_t magic, text, data, size;

	if(len < sizeof(hdr))
		return -1;
	memcpy(&hdr, buf, sizeof(hdr));

	magic = l2be(hdr.magic);
	text = l2be(hdr.text);
	data = l2be(hdr.data);

	switch(magic){
	default:
		return -1;
	case I_MAGIC:
	case S_MAGIC:
		break;
	}

	size = sizeof(hdr);
	if(magic & HDR_MAGIC)
		size += 8;
	size += text;
	if(size < text || size > len)
		return -1;
	size += data;
	if(size < data || size > len)
		return -1;

	return 0;
}

void plan9_x86_usage(void)
{
	printf("    --ini=FILE		Use FILE as plan9.ini\n");
	printf("    --append=STING	Append to boot parameters\n");
}

static int
e820conf(struct kexec_info *info)
{
	struct memory_range *r;
	int n, t;

	conf += snprintf(conf, confend-conf, "*e820=");
	r = info->memory_range;
	for(n = info->memory_ranges; n > 0; n--, r++){
		switch(r->type){
		default:
			continue;
		case RANGE_RAM:
			t = 1;
			break;
		case RANGE_RESERVED:
			t = 2;
			break;
		case RANGE_ACPI:
			t = 3;
			break;
		case RANGE_ACPI_NVS:
			t = 4;
			break;
		}
		conf += snprintf(conf, confend-conf, "%d %.16llx %.16llx ", t, r->start, r->end+1);
		if(conf >= confend)
			break;
	}
	if(conf >= confend)
		return -1;
	*conf++ = '\n';
	return 0;
}

static int
optconf(int argc, char **argv)
{
	long opt;
	char *buf;
	off_t nbuf;

	/* See options.h -- add any more there, too. */
	static const struct option options[] = {
		KEXEC_ARCH_OPTIONS
		{ "ini",1, 0, OPT_MOD },
		{ "append",1, 0, OPT_CL },
		{ 0,0, 0, 0 },
	};
	static const char short_options[] = KEXEC_ARCH_OPT_STR "";

	while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
		switch(opt) {
		case OPT_CL:
			conf += snprintf(conf, confend-conf, "%s\n", optarg);
			if(conf >= confend)
				return -1;
			break;
		case OPT_MOD:
			buf = slurp_file(optarg, &nbuf);
			if(buf == NULL)
				return -1;
			if(conf + nbuf >= confend)
				return -1;
			memmove(conf, buf, nbuf);
			conf += nbuf;
			break;
		}
	}
	return 0;
}

int plan9_x86_load(int argc, char **argv, const char *buf, off_t len,
	struct kexec_info *info)
{
	struct aouthdr hdr;
	struct entry32_regs regs32;
	uint32_t magic, entry, text, data, align;

	memcpy(&hdr, buf, sizeof(hdr));
	magic = l2be(hdr.magic);
	entry = l2be(hdr.entry);
	text = l2be(hdr.text);
	data = l2be(hdr.data);

	buf += sizeof(hdr);
	if(magic & HDR_MAGIC)
		buf += 8;

	entry &= ~0xF0000000;
	align = entry & 0xFFF;

	add_segment(info, buf-align, text+align, entry-align, text+align);
	add_segment(info, buf+text, data, PGROUND(entry + text), data);

	if(e820conf(info) < 0)
		return -1;
	if(optconf(argc, argv) < 0)
		return -1;
	if(conf >= confend)
		return -1;
	*conf = 0;

	add_segment(info, confbuf, sizeof(confbuf), CONFADDR&~0xFFF, sizeof(confbuf));

	/* Load the setup code */
	elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, ULONG_MAX, 1, 0);
	
	elf_rel_get_symbol(&info->rhdr, "entry32_regs", &regs32, sizeof(regs32));
	regs32.eip = entry;
	elf_rel_set_symbol(&info->rhdr, "entry32_regs", &regs32, sizeof(regs32));
	return 0;
}
_______________________________________________
kexec mailing list
kexec@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/kexec

[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux