Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: x86 assembly questions



On Oct 4,  7:08am, Emmanuel Dreyfus wrote:
} 
} I am working on multiboot 2 support in the NetBSD kernel, and I experience
} a few problems with EFI bootstrap.
} 
} In EFI, the kernel is loaded at 0x4078000, while the code in i386 locore.S 
} assumes it is at 0x100000. For that reason, native bootstrap startprog32 in
} src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S  copies the kernel
} from the loaded address to 0x100000.
} 
} We cannot assume a multiboot 2 compliant loader will do that for us. Hence
} I introduced an EFI32 entry point in locore.S and adapted the code
} from startprog32 to copy the kernel in locore.S. The kernel copy is done
} by a rep movsl instruction:
}    x0x40780b1       rep movsl %ds:(%esi),%es:(%edi) 
} 
} At that time, I have:
} %esi 0x4078000
} %ds       0x10
} %edi  0x100000
} %es       0x10
} %ecx  0x4ef400
} 
} First question: how %ds and %es are used here? They are supposed to 
} determine the higher bits of addresses used by rep movsl, but if I 

     This is only true in real mode (i.e. the way the original 8086
ran).  UEFI runs in the native mode of the processor (either 32-bit
or 64-bit).  In these modes, they are actually indexes into the
segment descriptor table.  You would have to look there to find
the start and length of the segment.  The addresses in %esi and
%edi are added to the start of the appropriate segment.

} step in rep mosvl, I can see the copy is indeed done from 0x4078000
} to 0x100000, just like if %ds and %es were ignored or set to zero.

     It is likely that the entry in the segment descriptor table
has the start set to 0 and the length set to maximum.  This is the
most common way of doing things and the segments are never changed
(i.e. segmentation is effectively disabled).  The exception is i386
PAE where segmentation comes back into play in order to be able to
access more than 4G.

} Then %ecx should contains the size in sizeof(long). I understand it 
} should copy from 0x100000 to 0x100000 + (4 * 0x4ef400), which is 
} 0x14bd000, but when I break after rep movsl instruction, the code 
} at 0x40780b3 has been clobered. This suggests the copy went too 
} far and I did not correctly understood how rep movsl works. Where is
} my error?
} 
} Last question: modifying %ss raises an exception. Why?

     Again, the %Xs registers are really indexes into the segment
descriptor table.  You can't modify them willy nilly.

}-- End of excerpt from Emmanuel Dreyfus


Home | Main Index | Thread Index | Old Index