Plan 9 from Bell Labs’s /usr/web/sources/contrib/rsc/load/load.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <a.out.h>
#include "load.h"

#define MB (1024*1024)

uchar *kernel = (uchar*)MB;

ulong
swap(ulong p)
{
	return (p<<24)|(p>>24)|((p<<8)&0x00FF0000)|((p>>8)&0x0000FF00);
}

void
_main(void)
{
	extern char edata, end;
	int n;

	memmove(kernel, &edata, MB);
	memset(&edata, 0, &end-&edata);

	cgainit();
	if(iskernel(kernel))
		run(kernel);
	if(isgzip(kernel)){
		print("GZ...");
		if((n=gunzip((uchar*)(2*MB), 2*MB, kernel, MB)) < 0){
			print("gzip failed.");
			exits(0);
		}
		if(n >= 2*MB){
			print("too big.");
			exits(0);
		}
		memmove(kernel, (uchar*)(2*MB), n);
		if(iskernel(kernel))
			run(kernel);
	}
	print("unrecognized file");
	exits(0);
}

int
iskernel(void *v)
{
	Exec *exec;
	
	exec = v;
	if(swap(exec->magic) == I_MAGIC)
		return 1;
	return 0;
}

void
run(void *v)
{
	ulong entry, text, data;
	uchar *base;
	Exec *exec;
	
	base = v;
	exec = v;
	entry = swap(exec->entry);
	text = swap(exec->text);
	data = swap(exec->data);
	entry &= ~0xF0000000;
	memmove(base+ROUND(32+text, 4096), base+32+text, data);
	print("LOAD...\n");
	((void(*)(void))entry)();
	print("exec failed");
	exits(0);
}

int
isgzip(void *v)
{
	uchar *p;
	
	p = v;
	if(p[0] == 0x1F && p[1] == 0x8B)
		return 1;
	return 0;
}

void*
malloc(ulong n)
{
	static char *brk;
	extern char end;
	void *v;
	
	if(brk == nil)
		brk = (char*)0x00400000;
	n = (n+3)&~3;
	v = brk;
	brk += n;
	return v;
}

void
free(void*)
{
}

void
putc(char c)
{
	cgaputc(c);
}

void
puts(char *s)
{
	for(; *s; s++)
		putc(*s);
}

int
print(char *fmt, ...)
{
	char *p, *s, buf[20];
	static char *hex = "0123456789abcdef";
	ulong x;
	long d;
	int sign;
	va_list arg;
	
	va_start(arg, fmt);
	for(p=fmt; *p; p++){
		if(*p == '%'){
			p++;
			switch(*p){
			case 'p':
			case 'x':
				x = va_arg(arg, ulong);
				s = buf+sizeof buf;
				*--s = 0;
				while(x > 0){
					*--s = hex[x&15];
					x /= 16;
				}
				if(s == buf+sizeof buf)
					*--s = '0';
				puts(s);
				break;
			case 'd':
				d = va_arg(arg, ulong);
				if(d == 0){
					puts("0");
					break;
				}
				if(d < 0){
					d = -d;
					sign = -1;
				}else
					sign = 1;
				s = buf+sizeof buf;
				*--s = 0;
				while(d > 0){
					*--s = (d%10)+'0';
					d /= 10;
				}
				if(sign < 0)
					*--s = '-';
				puts(s);
				break;
			case 's':
				s = va_arg(arg, char*);
				puts(s);
				break;
			case 0:
				return 0;
			default:
				break;
			}
			continue;
		}
		putc(*p);
	}
	return 0;
}

void
exits(char*)
{
	for(;;);
}


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.