ive put off OS production for a while, but have started up again. still trying to get a test kernel to boot. my question now is, hwo do i set up a valid data and stack segment? the kernel is loaded to 0x0800. shoudl i have the following line at teh top of my code?
org [0x0800]?
this coudl be wats messing it up. and i think my data and stack segments are invalid. how do i align the stack? i plan on this OS using pmode, 32bit
DS and SS
Re:DS and SS
SMTC, please. Without seeing what you've done, there's no way of knowing for sure.
Generally, though, when loading a second stage loader or a kernel while in real mode, you usually want the code segment offset (and hence your ORG statement) to initialized to 0000, and the code segment base set to the location you want to load your kernel at. You may have reasons to do otherwise, of course. The data and stack can be put more or less anywhere in memory between 1000:0000 and 9000:0000, inclusive, (there are other places they can go, but that large open space is particularly convenient), though you may want to have the data segment set to equal the code segment for the sake of simplicity if you don't have a lot of data. When setting the stack segment, make sure that interrupts are disabled. The stack pointer should be set to a double-word aligned address near the top of the available stack area, such as FFFE. I recommend reviewing the segmented memory model if you're going to be doing anything substantial in real mode (you can see reply #4 in this thread for a quick overview).
32-bit p-mode operations are completely different, of course. I'm afraid I can't give much advice on that subject, not yet at least.
Generally, though, when loading a second stage loader or a kernel while in real mode, you usually want the code segment offset (and hence your ORG statement) to initialized to 0000, and the code segment base set to the location you want to load your kernel at. You may have reasons to do otherwise, of course. The data and stack can be put more or less anywhere in memory between 1000:0000 and 9000:0000, inclusive, (there are other places they can go, but that large open space is particularly convenient), though you may want to have the data segment set to equal the code segment for the sake of simplicity if you don't have a lot of data. When setting the stack segment, make sure that interrupts are disabled. The stack pointer should be set to a double-word aligned address near the top of the available stack area, such as FFFE. I recommend reviewing the segmented memory model if you're going to be doing anything substantial in real mode (you can see reply #4 in this thread for a quick overview).
32-bit p-mode operations are completely different, of course. I'm afraid I can't give much advice on that subject, not yet at least.
Re:DS and SS
so even if my kernel is loaded at 0x8000, my org shoud still be 0x0000? perhaps i dont understand the org staements use. ive read teh nasm doc, btu coudl someone explain it?
Re:DS and SS
In an assembly language program the labels (Ok, most of them ) are all offsets to the start of the program. By placing an ORG statement at the start of the program you change the base address of the program so that the labels are correct for wherever you're loading the program to.
Eg
Without ORG Label_1 = 0x81
With ORG 0x70 Label_1 = 0x81 + 0x70 = 0xF1
So all you're basically doing is patching the labels with an ORG statement.
The alternative is to set the segment registers to operate in a segment which places the top of the program at 0x0000 in the segment. Then all your labels will work. Eg in a bootsector you would set DS = 0x07C0 at some point during your code. The good thing about not getting too reliant on ORG commands is that sooner or later you'll want to drop them in favour of a dynamic load time method of address relocation.
Eg
Without ORG Label_1 = 0x81
With ORG 0x70 Label_1 = 0x81 + 0x70 = 0xF1
So all you're basically doing is patching the labels with an ORG statement.
The alternative is to set the segment registers to operate in a segment which places the top of the program at 0x0000 in the segment. Then all your labels will work. Eg in a bootsector you would set DS = 0x07C0 at some point during your code. The good thing about not getting too reliant on ORG commands is that sooner or later you'll want to drop them in favour of a dynamic load time method of address relocation.
Re:DS and SS
The ORG statement sets the code entry point, that is, the location relative to the segment base where the code should be assembled to load at. All labels are calculated from that location. Thus, if your segment base is 0x0000, then ORG 8000 will assemble your code to begin at 0000:8000. For example, in the following code:elias wrote: so even if my kernel is loaded at 0x8000, my org shoud still be 0x0000? perhaps i dont understand the org staements use. ive read teh nasm doc, btu coudl someone explain it?
Code: Select all
[org 8000]
start:
mov cx, 0
gatherloop:
in al, 0x3E
jz end
mov [es:si], al
inc si
jmp gatherloop
end:
jmp $
However, using the ORG statement does not cause the code to automatically start running at 0000:8000 (absolute address 0x08000). In order to ensure that it begins at the correct place, you would have to ensure that control is correctly transferred to it by the first stage boot loader.
Now, there is no reason why you couldn't do this, but there are a few good ones why you probably shouldn't. First off, you've ignored half of the space in the segment you are using, giving you only 32Kbytes of working space - while this is probably plenty at this point, it will quickly become a limiting factor as you develop your kernel. Second, since the ORG statement in real mode is relative to the code segment base (held in the CS register) rather than an absolute value, if youd don't set your CS to what you want it to be first, you could be loading to 4A09:8000 (absolute address 0x52090) or 9000:8000 (absolute address 0x98000) just as easily as to 0x08000. If you want to load to a particular absolute address, it is better to use the segment base to set the entry point, and use an offset (and an ORG) of zero, I think.
Again, I don't know if this is relevant to your code or not. If you could show the code, it would make a big difference in how we can help you.
Re:DS and SS
I just do this in my kernel:
no org... here is code:
jmp Start
start:
some code
jmp $
nasm -f aout somefile.asm -o somefile.o
ld -Ttext=0x8000 -o somefile.tmp somefile.o -e 0x0
objcopy -R .note -R .comment -S -O binary somefile.tmp somefile.bin
no org... here is code:
jmp Start
start:
some code
jmp $
nasm -f aout somefile.asm -o somefile.o
ld -Ttext=0x8000 -o somefile.tmp somefile.o -e 0x0
objcopy -R .note -R .comment -S -O binary somefile.tmp somefile.bin