printing a char in C

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

Re:printing a char in C

Post by smurphy »

it looks like you are way out of control. :P

first, bx shouldnt be 0x1. your kernel should be loaded to some safe location, not es:0001 (es = 0x0000 i think, so that makes it copy the kernel to the IVT).

this is the "standard" code for doing it :)

- - - - - - - - - - - - - - - - - - - - - - -
load_os:
xor ax, ax
int 0x13 ; reset floppy
jc load_os ; if something goes wrong, try again :p

xor ax, ax
mov es,ax
mov bx, 0x1000 ; read them to es:bx (0000:1000)
mov ax,0x0201 ; read one sector
mov cx,0x0002 ; cylinder = 0, sector 2+
mov dx,0x0000 ; head = 0, drive=0 (A:)
int 0x13
jc load_os ; try until it works (may hang)
ret
- - - - - - - - - - - - - - - - - - - - - - -

maybe the jmp dword codesel:0x1 is wrong. try to change that to:

0xEA ; far jump
dw your_function
dw codesel

but your code should work :P

you may need to write the first code that is executed in your kernel in asm. i dont think c code is too stupid for being jumped to like that.
make a small entry code in asm and place it first in the kernel (so that the jmp from mbr actually jumps into a resonable code that dosnt crash the very first thing it does.. and compile your kernel into raw binary (not elf or exe or whatever))

check the other operating systems, and see how they did it! 8)

//smaffy
http://home.swipnet.se/smaffy
frank

Re:printing a char in C

Post by frank »

it does jump to the memory correctly...

I checked that out like this:

---------------
bits 32
jmp k
k: int 0x10
jmp main
main: main

times 512-($-$$) db 0
------------------
that makes the cpu crash, works correctly.

-----------------------
bits 32
jmp main
main: jmp main

times 512-($-$$) db 0
---------------------------------
this hangs...


so I think i've got there.
but when I tried to jump to the C kernel it just hangs:

int main()
{
asm("int $0x10");
asm("jmp 02");

while (1)
{

}
}

it should reboot...

this is what ndisasm kern.bin -b 32 shows me:
-------------------------
push ebp
mov ebp,esp
int 0x10
jmp 0x2
mov esi,esi
jmp short 0x10
jmp short 0x14
jmp short 0xc
mov esi,esi
leave
ret
mov esi,esi
---------------------------

made it a bit smaller:
---------------------
int main()
{
asm("int $0x10");
asm("jmp 02");
}
--------------------------

ndisasm kern.bin -b 32 shows me:
---------------------------
push esp
mov ebp,esp
int 0x10
jmp 0x2
leave
ret
--------------------------

btw its not 1 sector (512 bytes) long, should that matter?
frank

Re:printing a char in C

Post by frank »

finally, that makes my comp reboot... :D
I think that I get to the 32bit code....
but somehow outputing a char does not work.
Krom

Re:printing a char in C

Post by Krom »

i'm looking your code and is very very strange. i suppose this code is your boot sector.

First you put:

ORG 07C00H
mov [drive], dl

you do one move to the memory and you doesnt know where ds is pointing to. You didnt initialize ds, ss, sp, anything can be wrong here.

later you still didnt initialize es and read some sectors in es:bx where bx=1 so you doesnt know where are you reading the sectors. If es=0 this means that you are destroying the interrup table for real mode and you are still in real mode, nor you didnt dissable interrupts.

later you load gdt with one still uninitialized ds. Some bios put ds=0 some not. I suposse that your gdt have 2 selectors, 1 for code, base zero and limit 4Gb and another for data same as code.

i had lot of problems with boot sector before. Writing a boot sector is not as easy as you put. If everithing is good and the selectors is good, you should be able to write directly to screen throught 0xb8000
frank

Re:printing a char in C

Post by frank »

hmm ok.

the c code reboots... (its not 512 b ytes long)
and if I don't make an simple asm file 512 bytes long it reboots too
------------
bits 32
jmp main
main: jmp main
--------

so I think that is a problem too...
how do I make a c file 512bytes long?
frank

Re:printing a char in C

Post by frank »

new boot code:

org 07c00h
jmp readkern

readkern:
bits 16
mov ax,cs
mov ds,ax
mov es,ax

mov [drive],dl

mov bx,0x0
mov es,bx

mov ah,0x02
mov al,2
mov ch,00000000b
mov cl,00000010b
mov dh,00000000b
mov dl,[drive]
mov bx,0x1000 ; this memory place,please :]
int 13h

cli
lgdt[gdtr]
mov eax,cr0
or al,1
mov cr0,eax
jmp dword codesel:main32

bits 32
main32:
mov ax,datasel
mov ds,eax
mov ss,eax
mov esp,eax
mov es,eax

jmp dword codesel:0x1000
;db 0xEA
;dw 0x1000
;dw codesel

gdtr
dw gdt_end-1
dd gdt
gdt
nullsel equ $-gdt
gdt0
dd 0
dd 0
codesel equ $-gdt
dw 0ffffh
dw 0h
db 0h
db 09ah
db 0cfh
db 0h
datasel equ $-gdt
dw 0ffffh
dw 0h
db 0h
db 092h
db 0cfh
db 0h

gdt_end

drive db 0
times 510-($-$$) db 0
sign dw 0xAA55

it reboots...
why isn't it working?
frank

Re:printing a char in C

Post by frank »

ok I'm further now...
it shows an R in the right of the screen :)
------------
org 07c00h
jmp readkern

readkern:
bits 16
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,ax

mov [drive],dl

mov ah,0x02
mov al,2
mov ch,00000000b
mov cl,00000010b
mov dh,00000000b
mov dl,[drive]
mov bx,0x1000 ; this memory place,please :]
int 13h

cli
lgdt[gdtr]
mov eax,cr0
or al,1
mov cr0,eax
jmp dword codesel:main32

bits 32
main32:
mov ax,datasel
mov ds,eax
mov ss,eax
mov esp,eax
mov es,eax

;mov bx,0B800h
;mov es,bx
;mov byte[es:0],'f'
mov ebx,0xB809A
mov byte[es:ebx],'R'

; jmp dword codesel:0x1000
;db 0xEA
;dw 0x1000
;dw codesel
jmp hang
hang: jmp hang   

gdtr
dw gdt_end-1
dd gdt
gdt
nullsel equ $-gdt
gdt0
dd 0
dd 0
codesel equ $-gdt
dw 0ffffh
dw 0h
db 0h
db 09ah
db 0cfh
db 0h
datasel equ $-gdt
dw 0ffffh
dw 0h
db 0h
db 092h
db 0cfh
db 0h

gdt_end

drive db 0
times 510-($-$$) db 0
sign dw 0xAA55
------------

now lets see if I can do that in the kernel too...
frank

Re:printing a char in C

Post by frank »

jup i can do that with my asm kernel too ;D
now I'm gonna check if it works with my c kernel too...
frank

Re:printing a char in C

Post by frank »

hmm, I the c code doesn't get loaded...
i wrote it to sectors but it still outputs the old f (from the asm source)...

it isn't 512b long perhaps that is the problem...
(its 48b long)
frank

Re:printing a char in C

Post by frank »

hmm it doesnt get written if the file is not 512 bytes long :(
how do I get a c file 512b long?
frank

Re:printing a char in C

Post by frank »

hmm wrote zeros in the bin(after end of program) and that works...
(it prints a green A)
but how do I make it 512 bytes long in the C kernel?
K.J.

Re:printing a char in C

Post by K.J. »

Hmm...
1) use a linker script when you link your C file(more info about that here).
2) why not use GRUB for your bootsector for now? that would allow you to work on your kernel. You could make your own bootsector later when you are bored. ;)
3) There is an edit button on this forum. Use it(had you used the edit button, your last four posts could have been one post). :)

K.J.
frank

Re:printing a char in C

Post by frank »

>1) use a linker script when you link your C file(more info about that >here).

I've got a little script which puts it on a disk,
only freebsd cares if the sector size is 512 bytes or not...
(I made the c file 512bytes long , works.
Slack linux does not care about the sector size, so I'm gonna install that -- then I don't have to worry about it being smaller then the sector size :))


>2) why not use GRUB for your bootsector for now? that would >allow you to work on your kernel. You could make your own >bootsector later when you are bored.
why should I?
I didn't make this whole code for nothing ;)
also, I don't understand a thing of partitions
(biggest problem is that I don't know what sector I'm when booted (tried it using lilo), can I read the mbr in lilo or not? should I use lba or not?),

3) There is an edit button on this forum. Use it(had you used the edit button, your last four posts could have been one post).
hehe :P
frank

Re:printing a char in C

Post by frank »

sorry to reply in this topic again but
I can't call a function in C.

Code: Select all

void bla()
{

}

int main()
{
 bla();
 while (1)
 {
 }
}
does not work. (it does not work without bla(); either.
does anyone know why?

hmm, it does not jump to main... (that is what ndisasm shows me, it starts the first class :(
but I did set the entry point, so why doesn't it jump to the main?


>ld -o kern -Ttext 0x0 -e main kern.o
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re: Re:printing a char in C

Post by Pype.Clicker »

frank wrote:
hmm, it does not jump to main... (that is what ndisasm shows me, it starts the first class :(
but I did set the entry point, so why doesn't it jump to the main?

>ld -o kern -Ttext 0x0 -e main kern.o
hum... you seem to put too much confidence in your compiler. giving an explicit entry point to the linker do *not* make that function moved to the top of the executable (at offset 0) but rather records the address of the entry point in a special place of the file headers. In other words, it's your loader's job to identify the place of the main function and start it ...
Post Reply