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.