about the kernel

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.
Tom

Re:about the kernel

Post by Tom »

Your kernel on a floppy could be at max 1.44 M - 512 bytes.

Look at John Fine's web page for GDT stuff - download some code.

to find his page in google type:

"John Fine's home page" (with out the "'s), and click that frist link
adeelmahmood1

Re:about the kernel

Post by adeelmahmood1 »

hi
yeah i know that but i m asking how much one sector (any sector) can contain ( bytes) .. its for all the sectors had nothing to do with kernel ..???
and one more thing about ur code .. i m checking out the link u gave me and its a good one but cna u tell me what actually these "dw" and "dd" does ???
i mean syntax wise what they do ????i dont know what they do .. i can undertsand that "dw" defines a word but why there is no variable name for it ???
do u understand what i m trying to ask u ???
e.g for me it should be something like
var dw '0xffff'
u know something like this but what does
dw 0
can do .. i dont understand that ?? plz explain that
and also what is this "equ" thing
thanx for ur help
Tom

Re:about the kernel

Post by Tom »

one sect contains 512 bytes.

dd is double word, db is data byte
.bdjames

Re:about the kernel

Post by .bdjames »

Define Double, Define Byte
.bdjames

Re:about the kernel

Post by .bdjames »

c: const unsigned char c = 0;
c: #define c 0
nasm: c equ 0
gas c = 0

######################

c: unsigned char c = 0;
nasm c db 0
gas c .byte 0
adeelmahmood1

Re:about the kernel

Post by adeelmahmood1 »

hi
i have a ? about GDT
is there any GDT already defined in real mode .. ???
i mean if there is a GDT which exists in pmode .. cant we do it like when we switch to pmode we just point the old real mode GDT to be our new GDT for the pmode ...?
it might sounds stupid but u know thats a beginner question.. :)
thanx
PlayOS

Re:about the kernel

Post by PlayOS »

Would be good, but there is not GDT in real mode, the GDT in pmode is there because the way segments are accessed is different. In real mode you access a segment by putting it address into a segment register like

mov ax, 0x1000
mov es, ax

this give you access to segment 1 (the second segment out of 16), however in pmode now you cant access segment directly you must use a selector, hence the GDT holds these selectors, what this mean is to use a segment you must setup a valid selector for that segment, there is alot to a selector so you should read the intels docs to learn about them.

hope this helps.
adeelmahmood1

Re:about the kernel

Post by adeelmahmood1 »

hi
ok now i have a boot loader which can eanable Pmode and then jump to the C kernel .. now i need to make a binary file of that C kernel . but i m facing a problem ..
i m using gcc and ld for it .. this is my command
prompt:>
C:\>gcc -c kernel_c.c

C:\>ld -Ttext=0x1000 kernel_c.o -o kernel_c.exe
LD: warning: cannot find entry symbol _mainCRTStartup; defaulting to 00001000
kernel_c.o(.text+0x7):kernel_c.c: undefined reference to `__main'
*** and then after this warning no exe file has been created .. can some body help me .. i just need to make a binary file of this kernel_c.c ...
thanx for ur help
PlayOS

Re:about the kernel

Post by PlayOS »

When I create my binary files I use this:

gcc -c kernel.c
ld -Ttext=0x00001000 kernel.o -o kernel.exe

then I use objcopy to create the binary

objcopy -O kernel.exe kernel.bin

However, you are getting an error, not just a warning somewhere in your file you must be referencing __main without defining it, you should show us the code and we can help better.
Schol-R-LEA

Re:about the kernel

Post by Schol-R-LEA »

PlayOS wrote: In real mode you access a segment by putting it address into a segment register like

mov ax, 0x1000
mov es, ax

this give you access to segment 1 (the second segment out of 16)[...]
Not quite; this is a common misunderstanding, however, so it's no fault of yours. Segmentation is more complex in some ways than it might seem at first (and simpler in some others). I made the same mistake myself, and frankly still have some confusion on the point at times.

It is easy to get the impression that the x86 segmented memory consists of 16 fixed, separate memory areas of 64Kbytes apiece. However, this is not true; a segment is a potential area of memory, of any size up to 65535 bytes long, which can begin at any location aligned on a 16-byte boundary. Segments may be as small as one byte in size, and two or more segments may overlap each other - or even be exactly the same as each other (this is the case in DOS .com files - all of the segment registers are set to the same base location by DOS before the program is loaded).

The reason for this will become clear if you consider how real-mode addressing works. To get a full-qualified segmented address, you take the segment base, offset by one nibble (4 bits), and add it to the segment offset. Thus, in hex, address 0001:0000 becomes
[tt]
0001 - 16-bit segment base
0000 - 16-bit segment offset
-----
00010 - 20-bit absolute address
[/tt]

This, then, is the 'segment 1' in the sense that you mean (though it is only a segment to the extent that it is used as such by one in an address), but it is not 64Kbytes past origin of segment 0 (0000:0000), but 16 bytes. The two 'segments' overlap each other except at the first and the last 16 bytes. To put it another way, 0001:0000 is the same address as 0000:0010 expressed in two different ways.

This is also the source of the confusion of whether the boot sector is loaded at 0000:7C00 or at 07C0:0000 - both answers are, in fact, equally correct (as are 0001:7BFF and
06C0:1000, but those are less convienent to use). Which you use is a matter of personal choice; so long as you are consistent in how you use it, it will work out either way.

I know this a confusing system, but the Intel designers had there reasons for doing it this way, mostly having to do with hardware constraints that no longer apply. It was as much the cumbersome quality of this segmentation system as the 64K segment size limit that they developed the 32-bit protected mode, with it's then-generous 4G size limit. Now, even that has become a problem for some systems, and 64-bit designs like the Itanium and the Opteron are already in the works (though the Itanium has been stall for many years, and many, including me, feel that it would be best to totally drop the x86 design - which is, in a sense, being emulated rather than run directly on the newer chips anyway - and start from scratch). But I digress...

As I was saying, this particular method of making a 20-bit address out of two 16-bit parts has a number of surprising properties, not the least of which is that it adds up to slightly more than 20 bits - 65420 bytes more, in fact. IF you look at how the numbers add up again, you 'll see that
[tt]
F000
FFFF
------
FFFFF - 1048575 (1Mbyte), the largest possible 20-bit value

whereas,

FFFF
FFFF
------
10FFEF = 1114095 = 1048575 + (65535 - 15)
[/tt]

This extra bit of addressing range is called the High Memory Area, and has been the cause of some serious headaches since the introduction of the 80286 (which had 24 addressing lines instead of 20). When IBM built the AT, they found that even in real mode, you could access those extra 65420 bytes - which was a problem, because some important programs for the PC assumed that the memory would wrap around at FFFFF. To ensure compatibility, IBM set the address decoding up so that the 21st address line (the A20 line) was connected to a previously unused switch in the keyboard controller (an odd approach, to be sure, but it was cheaper than added a new, separate chip). By default, the switch was set to disable the A20 address line, and only by specifically resetting it could the memory 100000 and above be accessed (in either real or 16-bit protected mode). This design has remained enshrined in the design of PCs ever since, which is why you have to do the A20 Line Opening Ritual before accessing extended memory.

HTH. Comments and Corrections Welcome.
adeelmahmood1

Re:about the kernel

Post by adeelmahmood1 »

ok now i can compile my c code but when i compile it and make an exe file its too big .. i mean for a very simple hello world C program ..it created an exe file of 4KB and then bin file of 9KB ... is this normal :-\ or am i doing something wrong ...
PlayOS

Re:about the kernel

Post by PlayOS »

Yes, this is normal. Stupid, but normal, it has something to do with gcc wanting to align data, its like the x86 processor, the crap stuff should be off by default and only on if we turn it on.

You should try adding a global variable or two, I ended up with a 25KB binary file just by adding a global variable like this byte idt[2048] 2KB -> 25KB, I couldn't believe it, there is supposedly a way to turn it off, but I just use dynamic location, what I mean is I just set a certain piece of memory for my kernel stuff and then just use #define's to locate it, my kernel start at 4MB and all my kernel data is offset to that, so my page directory for the kernel, might be at 0x00001000 which is added to the base address for the kernel so physically my kernels page directory is loaded at 0x00401000.

Anyway, you haven't done any wrong, its the compiler, or linker whichever.
Tom

Re:about the kernel

Post by Tom »

also if you make a
int hi = 20; // GCC does bad things with this, you need
// to this:

int hi;

void function() {
hi = 20; }
adeelmahmood1

Re:about the kernel

Post by adeelmahmood1 »

hi
tom i m using ur bootloader to help myself in making mine .. so i think u can help me in this problem .. problem is that as soon as i set the Pmode suddenly after that if i do anything .. it just reboots .. only if i hang it just after setting pmode .. then it s fine but if i do anything else .. it just reboots ...
so wat do u think..?
Tom

Re:about the kernel

Post by Tom »

did you put up the GDT, and did you do a jmp codesel:PMode?
and set [bits 32]?
Post Reply