A small driver copies that image and puts it in some memory location. Now if I want to exec the 2.0 kernel so that it takes complete control and starts to run, what should be done? Any help is appreciated.
Thanks in advance.

Nope!. I don't want to reboot. Only 'exec'lukem95 wrote:overwrite the original kernel image on the HDD, then reboot
Code: Select all
*** First kernel ****
call RelocateFirstKernel ;e.g. copy your first kernel to 0x100000
...
*** this is the Load second kernel function ****
LoadThe2ndKernel:
jmp LoadThe2ndKernel+0x100004 ;jump to the relocated part at address 0x100000 plus this label's offset
;but SKIP the JMP opcode in the reloc part!!! thats because its 0x100004
....
*** this is where it should begin ***
call LoadTheSecondKernelFromHDD ;e.g. load your second kernel to first's ORG, thus overwriting the first to save RAM
;but no worries, since we are in the relocated part
call dword[FirstKernel_Org] ;call the first kernel's ORG to load the 2nd one
*** in the 2nd kernel at the beginning ****
mov esi,SecondKernel_CodeCopy
mov ecx,0x200
mov edi,0x200000 ;reserve 512 bytes of the code copying routines and relocate to the 2nd megabyte
rep movsb
...
*** the code copying routines, DO NOT execute them directly as you'll overwrite the 2nd kernel ***
...
SecondKernel_CodeCopy:
mov esi,0x100000 ;load the first kernel from the relocated part (1st megabyte)
mov ecx,Size_of_your_first_kernel_in_bytes
mov edi,[FirstKernel_Org]
rep movsb
...
;MAKE SURE YOUR STACK ISN'T SCREWED HERE!
;EVERY PUSH, PUSHAD, PUSHA etc MUST HAVE CORRESPONDING POP, POPAD, POPA, etc. !!!
ret ;This should return right after the "call RunSecondKernel", if your stack contents are alright.
...
** Second kernel's EXIT function ****
jmp sys_code:0x200000 ;sys_code is your CS selector
Thanks a lot for your time inflaterinflater wrote:A quick and dirty way:
1. Add into your second kernel a "EXIT" function, which does the same as in the part 4.
2. Run your first kernel and copy the whole kernel somewhere in free memory. Something like relocation, but don't free your first kernel's occupied memory. Now, jump to the relocated part.
3. In your first kernel's relocated part, load the second kernel at ORG, where the first kernel is loaded. Then, run the second kernel by CALLing
4. When the "EXIT" function is called in your second kernel, relocate the following "code-copying" routines somewhere in the free memory, then JMP to them. In there, load the first kernel from it's original relocation and copy it to the second kernel's ORG. Then run it by restoring the first kernel's EIP, which should point right after e.g. "call RunSecondKernel" - make sure your stack is alright.
5. In your first kernel, free the relocated space and the relocated "code-copying" routines. (Not necessary.)
In this example, I assume that the ORG of both kernels are the same.
Code: Select all
static uint32_t _secondKernelEntry;
void cmain(unsigned long magic, multiboot_info_t *mbinfo)
{
Elf32_Ehdr* ehdr;
unsigned char *secondKernelImage = (unsigned char *)0x39b00000;
..........
// This function reads 256 sectors (128 KB) to memory area secondKernelImage
readSectors(startSector,sectorCount);
......
....
// cast the 2nd kernel image to elf header
ehdr = (Elf32_Ehdr *)(secondKernelImage);
// get entry point of kernel_2
_secondKernelEntry = ehdr->e_entry;
printf("elf entry=0x%x\n",_secondKernelEntry);
__asm__ __volatile__(
" cld \n\t"
" pushl %esi\n\t"
" pushl %edi\n\t"
" pushl %ebx\n\t"
" pushl %eax\n\t"
" push %gs\n\t"
" push %fs\n\t"
" push %ds\n\t"
" push %es\n\t"
" leal _secondKernelEntry ,%eax\n\t"
" jmp *(%eax)\n\t" /*'call' gives GPF */
" pop %es\n\t"
" pop %fs\n\t"
" pop %gs\n\t"
" popl %eax\n\t"
" popl %ebx\n\t"
" popl %edi\n\t"
" popl %esi\n\t"
);
printf ("should not come here");
........
.......
return;
}
IMHO makes much more sense inventing a "hot load" protocol for the kernel.itisiuk wrote:and as Adek336 has said, you need to make sure the old kernel has setup the hardware state required by the new kernel.
i.e if paging is turned off when the new kernel 1st starts to run then youll need to make sure you turn paging off before you run the new kernel.