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