Booting VxWorks from LinuxBios
Christopher Stutts
stutts at innocon.com
Wed Feb 5 11:46:01 CET 2003
On Wed, 2003-02-05 at 10:37, Felix Radensky wrote:
> Hi, folks
>
> I'm trying to boot our VxWorks based application from using
> LinuxBios. On our board we have 512K Flash and 16M CF.
> VxWorks image is several megs in size, so I put it on CF.
>
> I use linuxbios and VxWorks boot loader, which is essentially
> a stripped down VxWorks kernel with 32-byte a.out header
> removed, to create a flash romimage. The idea is to let linuxbios
> load VxWorks boot loader into memory and let it load VxWorks
> from CF.
>
> Essentially, I've simply mimicked the romimage creation steps,
> just instead of linux kernel I use VxWorks bootloader.
>
> I can see that bootloader is successfully uncompressed into RAM,
> but nothing happens after I jump to it's code. According to VxWorks
> docs, bootloader should be copied to address 0x8000. I've tried to
> modify
> do_inflate.c and linuxbiosmain.c to load and jump to this address,
> but gunzip returned error.
>
> Now the question. Do you think this approach can work, or I am
> I doing something entirely wrong ?
>
> Should I convert a.out image of VxWorks bootloader into binary image.
>
> Can I modify linuxbios code to allow VxWorks boot loader to be loaded
> at 0x8000 ?
>
> Any other ideas will be much appreciated.
>
I did this experiment once, except I executed the full-up vxWorks kernel
instead of the bootloader. I believe that in addition to jumping to
8000h physical, I needed to switch to real mode, and that the
segment:offset needed to be 800:0.
//copy 1 flash page to vxworks start address
memcpy((void *)0x8000, (void *)0xfffe0000, 0x20000);
//patch the code in flashOSBootasm()
/* Code to be run at 0x800:0 expects real mode, so flashOSBootasm()
performs a 2 part mode switch. The 1st part is loading all
segment regs
with 16-bit segments, including jumping to a 16-bit code segment
in
protected mode. The GDT in intel_start32.S has a selector 0x28
with
base 0xf0000 & limit 0xffff. 0x28 therefore maps to the BIOS,
but
offsets are exactly 0xf0000 lower than in a flat segment. There
is
a jmp 28:0000 instruction in flashOSBootasm(), followed
immediately
by the flat32 offset of the actual code to be jumped to. So
right here,
we get a pointer to the code to be jumped to, read that address
embedded
in the 4 bytes preceding the code, and copy the low 2 bytes to
the jump
instruction in the x bytes preceding _that_. You
really have to trace through the code with an ICE to see what
really happens.
The 2nd part of the mode switch, after the cr0 reg is changed, is the
jump
to a real-mode segment offset address. */
pc = (unsigned char *)offset_patch_address; //553
pc2 = pc;
pc -= (0x553 - 0x549);
pc2 -= (0x553 - 0x54f);
//unprotect the bios in shadow ram
c = csreadc(0x59);
cswritec(0x59, c | 0x20);
pc[0] = pc2[0];
pc[1] = pc2[1];
__asm__("wbinvd");
//do not write protect, we lose the changes! What the hell!
// cswritec(0x59, c);
flashOSBootasm();
}
Unfortunately I can't find the asm code. Still looking.
More information about the coreboot
mailing list