[Lguest] small program running as a guest

Rusty Russell rusty at rustcorp.com.au
Mon Jun 22 12:49:41 EST 2009


On Mon, 22 Jun 2009 09:17:27 am Matias Zabaljauregui wrote:
> Hello list,
>
> 	just want to share my first (successful) attempt to run a small program as
> a Lguest guest. I want to document all my steps so if someone else wants to
> try his own experiment, some documentation will be available. So if you
> find out I did something really stupid here, please let me know.
>
> 1) I use a linker script to create my elf with the executable segment at
> 0x100000 phys addr  and  0xc0100000 virt addr   (just like linux kernel)
>
> 2) Lguest will create the identity (y = x) and linear (y = x + 0xc0000000)
> mappings, so we don't need to worry about setting page tables (for this
> simple program)
>
> 3) Our elf stores the entry point, and lguest initializes eip with the
> corresponding value. Our entry point is in assembly:
>
> -----
> .section .start
> .globl start
> .func start
> start:
> 	movl $0xc0030000, %esp  # initial stack pointer
> 	call main		# jump to C code
> 1:	jmp 1b			# should not return, but if it does, spin.
> .endfunc
> -----
>
> 4) OK, enough assembly code for me... Now we have a stack and can jump to C
> code. I put everything in 1 file, just for testing but here only show
> main() function (the whole C code is at the end of this text):
>
> -----
> int main (void)
> {
> 	char welcome[] = "\n\nWelcome!\nThis is PuppyToy\nA minimal guest for
> Lguest\n\n"; extern char _start_bss, _end_bss;
>
> 	/*Initialize bss*/
> 	unsigned char *p = (unsigned char *) &_start_bss;
> 	while (p < (unsigned char *)&_end_bss)
> 		*p++ = 0;
>
> 	/* $LHCALL_LGUEST_INIT */
> 	kvm_hypercall2(1, (unsigned long)&lguest_data -
> lguest_data.kernel_address, 0);
>
> 	/* Say hi!*/
> 	print(welcome, sizeof(welcome));
>
> 	/* LHCALL_SHUTDOWN(LGUEST_SHUTDOWN_POWEROFF) */
> 	kvm_hypercall2(2, 0, 1);
>
> 	return 0;
> }
> -----
>
> 5) That's it. The rest of C code is made of existing data types embedded in
> my file, and the definition of print() function  based on (copied from)
> lguest's early_put_chars().
>
>
> Finally, one question: given the proximity of the deadline for this work,
> do you consider a realistic goal to even think in writing some sort of
> virtio-console 'driver' for my toy ?

It could be.  You need a fair bit of virtio ring infrastructure, but you can 
take some shortcuts: use a static buffer and put it in entry 0 of the 
descriptor table.  Then just increment the index when you want to publish it 
(and wait for the used count to increment).

This applies to receive as well as xmit.

> 	char scratch[100];  //why just 17 in boot.c ?

Because the buffer they give us is only 16 bytes long IIRC (though the code 
doesn't assume that).

Thanks!
Rusty.




More information about the Lguest mailing list