Just keeps rebooting

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.
mercury(confused)

Just keeps rebooting

Post by mercury(confused) »

I've been working on my Kernel, haven't gotten too far. I haven't even bothered with protected mode. I wrote some simple character output procedures in assembly, which use direct memory access starting at 0xB800 This is the asm code:


GLOBAL _bgdi_cout
GLOBAL _bgdi_setattrib
EXTERN _c_main

SECTION .bss
attribute resb 1
position resw 1

SECTION .data
MemoryBase equ 0xB800

SECTION .text

start:
call _c_main
jmp $

_bgdi_setattrib:
push ebp
mov ebp, esp
mov al, [ebp + 8]
mov [attribute], ah
ret

_bgdi_cout:
push ebp
mov ebp, esp
mov al, [ebp + 8]
mov ah, [attribute]
mov ebx, [MemoryBase]
add ebx, [position]
mov [ebx], al
inc ebx
mov [ebx], ah
inc word [position]
inc word [position]
pop ebp
ret

the c code is:

extern void bgdi_cout();
extern void bgdi_setattrib();

void c_main() {
bgdi_setattrib(7);
bgdi_cout('c');
}

What am I doing wrong that it just keeps causing the computer to reboot? It can't be a protected mode problem with interrupts, I'm not using any.... If anybody can help, I would appreciate it a lot. I started out knowing I'd have a lot of trouble writing this thing, but maybe I'm just not ready...
Code Slasher

RE:Just keeps rebooting

Post by Code Slasher »

hi,
this is my first post here so hello to everyone.
okay to your problem,
first your c definitions are not correct cause you define the functions with no parameters and then you are calling it with parameters.
try
void bgdi_cout(char inchar);
void bgdi_setattrib(int attribute);
tell us how you are compiling and linking1
Code Slasher

RE:Just keeps rebooting

Post by Code Slasher »

sorry forgot something
attribute and position are not defined ie they have no value so they could be anything as they are in the bss
try
1. putting them in the data segment and not bss
2. assign them initial values
segment .data
attribute db 0
position  dw 0
mercury

RE:Just keeps rebooting

Post by mercury »

I thought last time I tried doing that, it said it was defined more than once.. Oh well. I'll try again.
mercury

RE:Just keeps rebooting

Post by mercury »

If I put them in the data segment and define them, can I still redefine them like I was doing? I thought the db/dw, etc ended up as being like constants. Sorry, I'm a little more used to higher level programing languages I learn RELATIVELY fast, but doesn't seem to be fast enough. Thanx for the help, I'll try everything and see how it ends up.
mercury

RE:Just keeps rebooting

Post by mercury »

It still reboots. I can't figure out how. Can anybody help?
I put:
MemoryBase equ 0xB800
attribute db 7
position db 0
in the code section


changed the c externs to:

extern void bgdi_cout(unsigned char c);
extern void bgdi_setattrib(int attrib );

linked using:
ld -Ttext 0xFF800000 --oformat binary -o kernel.bin kernel.o bgdi.o
Should I put the actual output procedures in bgdi.asm and the code that calls _c_main in another file(kernel_asm.asm) ?
mercury

RE:Just keeps rebooting

Post by mercury »

Well, I now know that it's something to do with the memory access this is what I have for one of my functions:

bgdi_cout:
mov bx, 0xb800
mov es, bx
mov di, [position]
mov [es:di] , al
mov dl, [attribute]
mov [es:di + 1], cl
ret

I'm working in real mode, using NASM to compile LD -Ttext 0xFF800000 --oformat binary to compile Any tips?
anon

RE:Just keeps rebooting

Post by anon »

>-Ttext 0xFF800000

that won't work in real mode; you need an address < 64K

you might need a BITS 16 at the start of SECTION .text

use NDISASM to look at the binary file produced by the linker, see if it's correct
mercury

RE:Just keeps rebooting

Post by mercury »

Ttext 0xFF800000 works fine for me. As long as I don't do certain things. I've gotten direct access to the video card memory to work, well, when writing one character at a time. And I use BITS 32. However, that's only if I do that in c, and then link the assem code which just calls the C function. So I don't quite get that...
Code Slasher

RE:Just keeps rebooting

Post by Code Slasher »

hi,
you can't use 32bit protected mode flat memory code gener
ated by gcc with 16 bit real mode code.
you will have to switch to pmode before you can use the 32 bit part
mercury

RE:Just keeps rebooting

Post by mercury »

First, I can't really figure out how to switch to protected mode.
Second, why does this work then?

short attribute = 0x07;
int Cposition = 0x00;
int TextBase = 0xB8000;

void bgdi_cout(char c) {
char *address = (char *)(TextBase + Cposition);
char *cadr = &c;
*address = *cadr;
address = address + 1;
*address = attribute;
Cposition = Cposition + 2;
} isn't that the same as...

bgdi_cout:
mov ebx, 0xb8000
mov es, ebx
mov di, [position]
mov [es:di] , al
mov dl, [attribute]
mov [es:di + 1], cl
ret

? This is what is really confusing me... I thought those two were basically the same or am I doing something wrong? I dunno. Maybe I should add 0xb8000 and position and then mov [address], al not that es:di stuff?
rexlunae

RE:Just keeps rebooting

Post by rexlunae »

db, dw, dd, etc just reserve space for data.  They are not like #defines, they can have values mov'ed into them later.  If you specify a value after you define them they will be initialized to that value.
rexlunae

RE:Just keeps rebooting

Post by rexlunae »

Lets get a few things straight here.

First:  What is your C compiler?  is it gcc, djgpp, something else?  The way your compiler works may have a major impact on whether or not your C code is equivalent to your asm code.  And if you have any doubt, try compiling to assembly (-S is the option in gcc).

Second:  In read mode, you simply MUST use addresses < 64k.  If you need to access more memory, you have to either switch into protected mode, or use Intel's segmentation to specify a different segment.  Linking at an address like 0xFF800000 has the potential to create very strange problems.  If you want to access video memory, you have these options.
1.  Switch to protected mode.
2.  Use a 32-bit segmented address.
3.  Use the bios calls that are still available in real mode.
I recommend that unless you are writing a DOS clone, you should figure out how to get into protected mode.  It isn't hard.  All you need to do is set up a GDT (end set the GDTR to point to it), set bit 0 in CR0, load new segment register values, and jump into protected mode code.  Or, if you don't want to do that, you could use a bootloader like GRUB to switch you into protected mode (it even enables the A20 address line for you, a demonic little feature which you probably havn't delt with yet), and then all you have to do is write 32-bit protected mode code that uses a flat memory model.  I ended up using GRUB even after writing a working boot loader to get into protected mode that worked, because it is so much easier and GRUB has a lot of nice features.
rexlunae

RE:Just keeps rebooting

Post by rexlunae »

1    bgdi_cout:
2    mov ebx, 0xb8000
3    mov es, ebx
4    mov di, [position]
5    mov [es:di] , al
6    mov dl, [attribute]
7    mov [es:di + 1], cl
8    ret

Look at line 1.  You have the wrong segment value.  Should be 0xb800 not 0xb8000.  The segment starts at 0xb800, which is physical address 0xb8000.  In line 2 (its surprising that your assembler didn't warn or error on this), you mov that 32-bit register into a 16-bit register, truncating the segment to 0x8000.  You had this right in other examples you posted...it is a typo?

Fix that, and also try linking at the right address, and I'll bet this will work.  BTW... How is this being loaded?  Is it a boot sector, or something else?  That may impact what address it needs to be linked to start at.


Try this.  I havn't done so much as try to compile it, but I think it may help.

GLOBAL _bgdi_cout
GLOBAL _bgdi_setattrib
EXTERN _c_main

SECTION .bss
attribute resb 1
position resw 1

SECTION .data
MemoryBase equ 0xB800

SECTION .text

start:
call _c_main
jmp $

_bgdi_setattrib:
push ebp
mov ebp, esp
mov al, [ebp + 8]
mov [attribute], ah
ret

_bgdi_cout:
push ebp
mov ebp, esp
mov al, [ebp + 8]
mov ah, [attribute]
mov bx, MemoryBase ;MemoryBase is a constant, not a memory location.  You don't want [] around it.
mov es, bx ;Set the segment
mov di, [position] ;Set the offset
mov [di], al ;write the char to es:di
inc bx
mov [di + 1], ah
inc word [position]
inc word [position]
pop ebp
ret

the c code is:

extern void bgdi_cout(char);
extern void bgdi_setattrib(char);

void c_main() {
bgdi_setattrib(7);
bgdi_cout('c');
}
mercury

RE:Just keeps rebooting

Post by mercury »

I'm using GCC and NASM using GRUB to boot. My main problem is my lack of knowledge in x86 asm language for one thing. I'm more familier with 680x0 I miss my Atari :(

In any case, going into 0xFF800000 works fine normally, in fact, it's what one tutorial TOLD me to use, dunno why. You said grub sets up protected mode, do you have to do anything to tell it to start in protected mode or is that automatic? Maybe there's one of my problems? I'm thinking I'm in real mode but I'm not? I know that in C at one point I could have it print out characters to the screen, I can't remember if it could print out an entire string though. Can you set up the IDT and design the interrupts in C?

I might really be better off not working on this thing anymore... just might not be ready for it...
Post Reply