>> If i decide to use grub later on, dosn´t grub go into pmode and stuff for me?
Yes. pmode and sets a20, no paging enable, gdt code/data is at full 0-4gb, no stack.
>> If thats the case, then it would be easy just to skip the 'loader.sys' without any changes in my kernel..
Very much so. You need a header within the first 8kb of your kernel though to boot from a multiboot bootloader.
http://www.mcc.ac.uk/Documentation/grub ... t_toc.html
Moose.
Memory problem
RE:Memory problem
It´s perfect! I can use my bootsector code and 'loader.sys' if i want the OS on a floppy and grub on a harddrive..
I know about the multiboot header, but i have not even started on my kernel yet...
I got some seriuos truble getting into pmode in 'loader.sys' that i got to fix first..
thanks to all answers..
/ Christoffer
I know about the multiboot header, but i have not even started on my kernel yet...
I got some seriuos truble getting into pmode in 'loader.sys' that i got to fix first..
thanks to all answers..
/ Christoffer
RE:Memory problem
Aside from the fact that you forgot to use the [BITS 16] directive, the problem is that you are mixing up the segment bases and offsets.
The NASM [ORG} directive (and the equivalents in FASM and GAS) sets the value of a segment offset; that is to say, it is the local address within the code segment that the code is loaded at, and the value which IP is set to when the program begins. In effect, [ORG 0x7C00] has the same effect as if there had been a 'JMP NEAR 0x7C00' statement, just before the program ran.
The instruction 'mov ax, [d|e|g|s]s', on the other hand, sets the given segment *base*, the location from which the segment offsets are calculated to get the location in absolute memory.
Finally, a 'jmp far xxxx:yyyy' has the effect of setting CS to xxxx and IP to yyyy.
The practical upshot of this is that if you use an [ORG 0x7c00] at boot up, then CS must be 0x0000, or the labels will be calculated incorrectly. While most BIOSes will do this as a matter of course, not all do, so you should always have a far jump to the beginning of the code, before any local non-relative references, to ensure it is correct.
Similarly, if you mean to have your data and stack segments match the CS segment, then you should use 'mov ax, cs' and then load the other segment registers from that (this is faster in any case, as it does not involve any memory reads).
Finally, when setting the stack segment, you need to disable interrupts; otherwise, if any interrupt does occur during this time, the interrupt call may end up using an invalid stack setting and the return would be mangled. While interrupts are disabled, you should also set the SP register to the *top* of the stack, offset by four bytes to ensure proper alignment.
So, the code you would want should be something like this:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[bits 16]
[org 0x7C00]
entry: ; address should be 0000:7C00
jmp 0000:start ; sets CS:IP to 0000:7C05
start: ; address should be 0000:7C05
mov ax, cs ; get segment value from CS
mov bx, 0xfffc ; get value for top of new stack
cli ; clear interrupts
mov ss, ax ; set stack segment
mov sp, bx ; set sp to top of stack
sti ; reset interrupts
mov ds, ax ; set CS == DS == ES == FS == GS
mov es, ax
mov fs, ax
mov gs, ax
;; continue with code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
The NASM [ORG} directive (and the equivalents in FASM and GAS) sets the value of a segment offset; that is to say, it is the local address within the code segment that the code is loaded at, and the value which IP is set to when the program begins. In effect, [ORG 0x7C00] has the same effect as if there had been a 'JMP NEAR 0x7C00' statement, just before the program ran.
The instruction 'mov ax, [d|e|g|s]s', on the other hand, sets the given segment *base*, the location from which the segment offsets are calculated to get the location in absolute memory.
Finally, a 'jmp far xxxx:yyyy' has the effect of setting CS to xxxx and IP to yyyy.
The practical upshot of this is that if you use an [ORG 0x7c00] at boot up, then CS must be 0x0000, or the labels will be calculated incorrectly. While most BIOSes will do this as a matter of course, not all do, so you should always have a far jump to the beginning of the code, before any local non-relative references, to ensure it is correct.
Similarly, if you mean to have your data and stack segments match the CS segment, then you should use 'mov ax, cs' and then load the other segment registers from that (this is faster in any case, as it does not involve any memory reads).
Finally, when setting the stack segment, you need to disable interrupts; otherwise, if any interrupt does occur during this time, the interrupt call may end up using an invalid stack setting and the return would be mangled. While interrupts are disabled, you should also set the SP register to the *top* of the stack, offset by four bytes to ensure proper alignment.
So, the code you would want should be something like this:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[bits 16]
[org 0x7C00]
entry: ; address should be 0000:7C00
jmp 0000:start ; sets CS:IP to 0000:7C05
start: ; address should be 0000:7C05
mov ax, cs ; get segment value from CS
mov bx, 0xfffc ; get value for top of new stack
cli ; clear interrupts
mov ss, ax ; set stack segment
mov sp, bx ; set sp to top of stack
sti ; reset interrupts
mov ds, ax ; set CS == DS == ES == FS == GS
mov es, ax
mov fs, ax
mov gs, ax
;; continue with code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RE:Memory problem
No it won´t!
If you at least had read the first posting of this thread.. *lol*
In the very first post i write this (or something like it):
"I want the kernel to know it´s on address 0xFFFF:0x0010 (1mb). How?"
In a later posting i write this:
"It dosn´t matter anymore, i rewrote the bootsector code to load 'loader.sys' that sets up the A20-gate and pmode before starting the 'kernel.sys'."
And the code i showed hadn´t [BITS 16] becasue they was just examples (cuts of code _after_ the [BITS 16] was already written).
Anyway nice explaintion of how it works.. (for you how didn´t know that..)
/ Christoffer
If you at least had read the first posting of this thread.. *lol*
In the very first post i write this (or something like it):
"I want the kernel to know it´s on address 0xFFFF:0x0010 (1mb). How?"
In a later posting i write this:
"It dosn´t matter anymore, i rewrote the bootsector code to load 'loader.sys' that sets up the A20-gate and pmode before starting the 'kernel.sys'."
And the code i showed hadn´t [BITS 16] becasue they was just examples (cuts of code _after_ the [BITS 16] was already written).
Anyway nice explaintion of how it works.. (for you how didn´t know that..)
/ Christoffer