Moving kernel_entry to LOADADDR
I'm planning to work with a very minimal boot loader, and I'd like to hard-code a jump to kernel_entry in my boot loader. I got tired of having kernel_entry moving around, so I just moved it to the top of head.S, just afte the ".fill 0x280". That places kernel_entry at the same place every time. It's always at LOADADDR+0x280.
But wait a minute... the 0x280 is there to leave room for the exception vectors. Doesn't that only make sense if LOADADDR=0x80000000? Isn't this allocating the space for the exception vectors twice? Why not remove the .fill, then the kernel entry point will always be exactly LOADADDR? This would break any configuration that has LOADADDR=0x80000000, but the only configuration like that is CONFIG_ALGOR_P4032, and that could easily be modified to LOADADDR=0x80000280 to get the same effect.
I also removed the .fill, and now kernel_entry is always exactly LOADADDR, and that makes my bootloader easier to maintain.
Is this worth changing in cvs, or did I miss something?
Thanks.
Gerald
Gerald,
Quoted 4 lines
to hard-code a jump to
kernel_entryin my boot loader. I got tired of havingkernel_entrymoving around, so I just moved it to the top ofhead.S, just afte the ".fill0x280". That placeskernel_entryat the same place every time. It's always atLOADADDR+0x280.
Don't know about all .fill & exception vecs... the trick I use in my (vr)boot loader...
KERNEL_ENTRY=$(shell awk '/kernel_entry/{print "0x" $$1}' $(LINUX_SRC)/System.map) CFLAGS+=-DKERNEL_ENTRY=$(KERNEL_ENTRY)
And compile boot.S or whatever your bootloader is.
But a fixed, well-known offset can't be a bad thing either.
Geoff
Signature · 1 line
Geoffrey Espin [email protected]
Quoted 1 line · Gerald Champagne
Is this worth changing in cvs, or did I miss something?
Embed your kernel in your own bootloader, load the bootloader from fixed addr. In the bootloader move the kernel at any location you want and jump to the kernel entry. The kernel entry is known at compile time, so you can teach the bootloader. This way you won't disturb others.
Regards,
Gleb.
Quoted 4 lines · Gerald Champagne
I also removed the .fill, and now
kernel_entryis always exactly LOADADDR, and that makes my bootloader easier to maintain.Is this worth changing in cvs, or did I miss something?
How about just getting it from the ELF header? It's trivial.
Signature · 3 lines
+ Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: [email protected], PGP key available +
Quoted 6 lines
Date: Fri, 19 Oct 2001 15:20:33 +0200 (MET DST)
From: "Maciej W. Rozycki" <[email protected]>
To: Gerald Champagne <[email protected]>
Subject: Re: Movingkernel_entryto LOADADDR
Quoted 8 lines
Quoted 4 lines · Gerald Champagne
I also removed the .fill, and now
kernel_entryis always exactly LOADADDR, and that makes my bootloader easier to maintain.Is this worth changing in cvs, or did I miss something?
How about just getting it from the ELF header? It's trivial.
Because a bare bones bootloader may not know anything about ELF. The
simplest solution is to just stick a "jmp start_kernel" at LOADADDR right before the fill. Then the load address and the entry point are the same. Once the exception vectors get loaded, they'll overwrite the jmp, so no space is wasted and none of the LOADADDRs have to be changed.
Mike McDonald
[email protected]
Quoted 10 lines
Quoted 3 lines
How about just getting it from the ELF header? It's trivial.
Because a bare bones bootloader may not know anything about ELF. The
simplest solution is to just stick a "jmpstart_kernel" at LOADADDR right before the fill. Then the load address and the entry point are the same. Once the exception vectors get loaded, they'll overwrite the jmp, so no space is wasted and none of the LOADADDRs have to be changed.
That was my thinking.
Except the fill has nothing to do with exception vectors any more. It looks like at one time LOADADDR was always 0x8000_0000. Now that it's set to something else, the fill just leaves a hole for no reason. That's why I recommend removing it regardless of whether there's a use for my idea.
With the fill is gone, and since the kernel is not normally placed at 0x8000_0000, I suggest just moving kernel_entry to the top of head.S instead of putting a jump at the top of the file.
Also, compile tricks won't work (at least in my case). Normally the bootloader and the kernel are in two memories, often programmed in different ways. For example, a system normally has rom at the boot address at 0x1fc0_0000, ram at 0x8000_0000, and some other memory (flash, hard disk, whatever) storing a kernel (or kernels) somewhere else. Any compile time tricks require the boot rom to be reprogrammed when the kernel changes. That's part of what I wanted to avoid.
Gerald
Quoted 6 lines · Mike McDonald
Because a bare bones bootloader may not know anything about ELF. The
simplest solution is to just stick a "jmpstart_kernel" at LOADADDR right before the fill. Then the load address and the entry point are the same. Once the exception vectors get loaded, they'll overwrite the jmp, so no space is wasted and none of the LOADADDRs have to be changed.
This may be true, but grokking ELF far enough to find e_entry just a matter of looking at a fixed offset into the kernel image. Problems that require bootloaders to be simpler than that are pretty rare...
-Justin
Quoted 16 lines
Subject: Re: Moving
kernel_entryto LOADADDR
From: Justin Carlson <[email protected]>
To: [email protected]
Date: 19 Oct 2001 11:21:41 -0400Quoted 6 lines · Mike McDonald
Because a bare bones bootloader may not know anything about ELF. The
simplest solution is to just stick a "jmpstart_kernel" at LOADADDR right before the fill. Then the load address and the entry point are the same. Once the exception vectors get loaded, they'll overwrite the jmp, so no space is wasted and none of the LOADADDRs have to be changed.
Quoted 5 lines
This may be true, but grokking ELF far enough to find
e_entryjust a matter of looking at a fixed offset into the kernel image. Problems that require bootloaders to be simpler than that are pretty rare...-Justin
But they do exist, especially in the embedded world. For instance,
I've run linux with boot loader out of a 1MB flash into 8MB of RAM. (VR4121 based system.) The kernel image stored in the flash had to be a compressed raw memory image inorder to fit in the flash. (The flash also had to have room to the initrd.) Adding ELF headers to the image would probably have pushed the size over the limit.
Mike McDonald
[email protected]
Quoted 5 lines · Gerald Champagne
I'm planning to work with a very minimal boot loader, and I'd like to hard-code a jump to
kernel_entryin my boot loader. I got tired of havingkernel_entrymoving around, so I just moved it to the top ofhead.S, just afte the ".fill0x280". That placeskernel_entryat the same place every time. It's always atLOADADDR+0x280.
Dont do this - Its easy to decode the elf stuff:
Basically this is the code needed to relocate the elf chunks
and return the entry point. I might have corrupted it a bit due to stripping unneeded bits but you will get the point. This code even clears bss chunk which the kernel will do itself again.
Elf32_Ehdr *fhdr = fb;
Elf32_Shdr *shdr;
int i;
if (fhdr->e_machine != EM_MIPS) {
printf("No Mips ELF\n");
return(0);
}
fhdr=(void *) KSEG1ADDR(fb);
shdr=fb + fhdr->e_shoff;
for(i=0;i<fhdr->e_shnum;i++,shdr++) {
if (shdr->sh_size <= 0)
continue;
if (shdr->sh_type == SHT_PROGBITS) {
memcpy((void *) KSEG1ADDR(shdr->sh_addr),
KSEG1ADDR(fb + shdr->sh_offset),
shdr->sh_size);
} else if (shdr->sh_type == SHT_NOBITS) {
memset((void *) KSEG1ADDR(shdr->sh_addr), 0x0, shdr->sh_size);
}
}
return((void *) fhdr->e_entry);Signature · 2 lines
Florian Lohoff [email protected] +49-5201-669912 Nine nineth on september the 9th Welcome to the new billenium