As far as I know, protected mode will be activated in kernel and in grub stages it still real mode. My misunderstanding is: In real mode, total memory available for use is less than 1MB but how grub can load the kernel and even root file system (usualy bigger than 1MB) to memory?
GRUB does not have to load the whole kernel into memory. The kernel image is split into two pieces:
- The real-mode kernel code, which is small and can be loaded within the 640kB threshold of available memory;
- The rest of the kernel, which runs in protected mode and is loaded after the first megabyte of memory.
The bootloader only loads the real-mode kernel code, which in turn bootstraps the rest (take a look at
arch/x86/boot/pm.c). This is how the process can stay within the memory limitations of running in real mode.
A small note: GRUB may run in both real mode and protected mode, depending on what it is doing. It may switch into protected mode for some things (some hardware detection, and menu display). You are right, however, in thinking that it is in real mode when it hits the kernel.
It can be done in real mode by means of BIOS int 0x15, 0x87 function. GDT must be filled appropriately for source and destination.
cx - number of bytes to move.
push edx push es xor ax, ax mov es, ax mov ah, 0x87 mov si, gdt int 0x15 jc error pop es pop edx ret gdt: times 16 db 0 dw 0xffff ; segment limit .src: dw 0 db 2 db 0x93 ; data access rights dw 0 dw 0xffff ; segment limit .dest: dw 0 db 0x10 ; load protected-mode kernel to 100000h db 0x93 ; data access rights dw 0 times 16 db 0 error: