how does the grub load the kernel at 1mb?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
asmboozer

how does the grub load the kernel at 1mb?

Post by asmboozer »

if in the link script file, 1mb address is specified. the grub will load the kernel at 1mb.

my question is:

is it done after entering PMODE?(I have not read the intel doc thoroughly,there may be other modes can access it i don't know).

otherwise i don't know how to access the address above 1Mb.
n3Ro

Re:how does the grub load the kernel at 1mb?

Post by n3Ro »

Yes, as far as i know GRUB is entirely running in 32bit protected mode and only switches to 16bit real mode for bios calls.
But another way to access addresses above 1mb would be the "unreal" mode, where you switch to protected mode, load a segment register with a 4gig segment, and switch back to real mode. With this segment you would be a able to address to whole 4G address space from real mode ;)
hendric

Re:how does the grub load the kernel at 1mb?

Post by hendric »

Hmm,I've never read about the source of GRUB. But as my thought, GRUB may access hard disk via PIO or return to real mode when reading data and switch 32 bit protected mode when moving data.
That's what I 've done for my simple kernel.
n3Ro

Re:how does the grub load the kernel at 1mb?

Post by n3Ro »

Code: Select all

/*
 *   int biosdisk_int13_extensions (int ax, int drive, void *dap)
 *
 *   Call IBM/MS INT13 Extensions (int 13 %ax=AX) for DRIVE. DAP
 *   is passed for disk address packet. If an error occurs, return
 *   non-zero, otherwise zero.
 */

ENTRY(biosdisk_int13_extensions)
   pushl   %ebp
   movl   %esp, %ebp

   pushl   %esi
   pushl   %ebx

   /* compute the address of disk_address_packet */
   movl   0x10(%ebp), %eax
   movw   %ax, %si
   xorw   %ax, %ax
   shrl   $4, %eax
   movw   %ax, %cx   /* save the segment to cx */

   /* drive */
   movb   0xc(%ebp), %dl
   /* ax */
   movw   0x8(%ebp), %bx
   /* enter real mode */
   call   EXT_C(prot_to_real)
   
   .code16
   movw   %bx, %ax
   movw   %cx, %ds
   int   $0x13      /* do the operation */
   movb   %ah, %dl   /* save return value */
   /* clear the data segment */
   xorw   %ax, %ax
   movw   %ax, %ds
   /* back to protected mode */
   DATA32   call   EXT_C(real_to_prot)
   .code32

   movb   %dl, %al   /* return value in %eax */

   popl   %ebx
   popl   %esi
   popl   %ebp

   ret
This is an example from the file asm.S of the grub source code. The "real_to_prot" and "prot_to_real" routines are also defined in this file. ;)

I think using PIO / own drivers would be too complicated for a boot loader, because there would have to be more drivers available than space on a 1,44" disk (look at the linux kernel^^)
Post Reply