having problems with printing messages
-
beyondsociety
having problems with printing messages
I am revamping my c code and I have noticed that when I run my code in bochs, the messages I have printed to the screen, get overwritten by other messages from functions I am calling to run.
What could be the cause of this. This is weird, because before I never had this problem. Its only when you re-write your code that you find even more problems then before. ;D
Thanks for the help.
What could be the cause of this. This is weird, because before I never had this problem. Its only when you re-write your code that you find even more problems then before. ;D
Thanks for the help.
-
nullify
Re:having problems with printing messages
If you've implemented task switching, there is a chance that your non-reentrant printing code is being entered multiple times, which would screw things up.
Also, pay extra attention to how you managed your cursor row/col variables. It sounds to me like at some point they might not be getting updated when they need to be.
Also, pay extra attention to how you managed your cursor row/col variables. It sounds to me like at some point they might not be getting updated when they need to be.
-
beyondsociety
Re:having problems with printing messages
I have not implemented task switching as of yet.If you've implemented task switching, there is a chance that your non-reentrant printing code is being entered multiple times, which would screw things up.
This is probably my problem, I will take a look at my update_cursor function and get back to you on the results. I might re-write my update_cursor function.Also, pay extra attention to how you managed your cursor row/col variables. It sounds to me like at some point they might not be getting updated when they need to be.
Update: After some testing, I figured out there is some kind of problem with my init_interrupts.c function as when it is called, it overwrites the previous messages.
-
beyondsociety
Re:having problems with printing messages
Why would my init_pics function mess up the cursor and thus overwrite my previous messages?
I wonder if there something wrong with that function.
I wonder if there something wrong with that function.
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:having problems with printing messages
if you messed up the 'outb' commands, it may happen ...
Also take care that an interrupt that occurs while you're printing something will not mess things.
it will depend on whether you cache the content of the position in memory or not and if you do, how you declare those cache variables to GCC (are they static ? or volatile ? or both ?)
Also take care that an interrupt that occurs while you're printing something will not mess things.
it will depend on whether you cache the content of the position in memory or not and if you do, how you declare those cache variables to GCC (are they static ? or volatile ? or both ?)
-
beyondsociety
Re:having problems with printing messages
I check into this.if you messed up the 'outb' commands, it may happen ...
How do I check this?Also take care that an interrupt that occurs while you're printing something will not mess things.
Can you give a better explanation of this.it will depend on whether you cache the content of the position in memory or not and if you do, how you declare those cache variables to GCC (are they static ? or volatile ? or both ?)
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:having problems with printing messages
let's suppose you have something like
It is probable that the variable video_current (for instance) or cursor_row and cursor_column are not referenced everytime the code modifies them. What the compiler could do -- as there's no function call until set_hw_... -- is to decide that it will use %eax as a cache for video_current, thus the function preamble will include some code like "mov eax,[video_current]" and "mov [video_current],eax will be issued just before "call set_hw ..."
In this configuration, any interrupt that occurs while the CPU is running kprint will not find the up-to-date version of the variable.
For instance
kprint("we're in main")
will start at video_current = 10 and prints 5 characters. Then an interrupt fires and
kprint("this is the interrupt handler") will be executed, which will also find video_current=10 (rather than 15!), so it will overwrite "we're" that has already been written.
kprint("we're in main")
is resumed and it continues printing chars " in main", overwriting "is the int".
Finally, what you see on screen is
"this in main[t]errupt handler"
instead of
"we're this is the interrupt handler in main[ ]".
Hope it's clearer this way.
One way you can force GCC to access the memory location for every variable reference is by declaring "volatile char *video_current".
Code: Select all
cursor_row;
cursor_column;
char *video_current;
char *video_start;
kprint(char *message)
{
for (;*message;message++) {
switch(*message) {
case '\n': cursor_row+=cursor_column/ROW_WIDTH;
cursor_column=0;
video_current=video_start+cursor_row*ROW_WIDTH*2;
default:
*video_current=*message;
video_current[1]=attributes;
cursor_column++;
}
}
set_hw_cursor_position(cursor_row, cursor_column);
}
In this configuration, any interrupt that occurs while the CPU is running kprint will not find the up-to-date version of the variable.
For instance
kprint("we're in main")
will start at video_current = 10 and prints 5 characters. Then an interrupt fires and
kprint("this is the interrupt handler") will be executed, which will also find video_current=10 (rather than 15!), so it will overwrite "we're" that has already been written.
kprint("we're in main")
is resumed and it continues printing chars " in main", overwriting "is the int".
Finally, what you see on screen is
"this in main[t]errupt handler"
instead of
"we're this is the interrupt handler in main[ ]".
Hope it's clearer this way.
One way you can force GCC to access the memory location for every variable reference is by declaring "volatile char *video_current".
-
beyondsociety
Re:having problems with printing messages
One way you can force GCC to access the memory location for every variable reference is by declaring "volatile char *video_current". Is this the way to do it?It is probable that the variable video_current (for instance) or cursor_row and cursor_column are not referenced everytime the code modifies them.
Why would a interrupt be triggered when my print function is called when maskable interrupts are disabled with CLI and non-maskable interrupts are disabled untill I call a interrupt?In this configuration, any interrupt that occurs while the CPU is running kprint will not find the up-to-date version of the variable.
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:having problems with printing messages
that's something you didn't mention.beyondsociety wrote: Why would a interrupt be triggered when my print function is called when maskable interrupts are disabled with CLI and non-maskable interrupts are disabled untill I call a interrupt?
Well, one obvious cause is that the interrupt is an exception.
If this is not the case either ... well ... i dunno, except if you call printf from printf (which you of course didn't, did you ?)
-
beyondsociety
Re:having problems with printing messages
How can I check this?Well, one obvious cause is that the interrupt is an exception.
I dont think this is my problem. Do you mean calling a printf function inside of the printf function? If this is the case, then no Im not that stupid.If this is not the case either ... well ... i dunno, except if you call printf from printf (which you of course didn't, did you ?)
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:having problems with printing messages
well, maybe the best way for you to solve this out will be to have bochs running step by step from the start of the 'print' command until it ends. I know this is boring as hell, but at least it will show you what's going on.
Another possible way to solve this is to ask Bochs to enable the call trace (see bochs first aid kit in .:QuickLinkz:. for more info), so that you'll know what function/interrupt/exception calls are made.
At this level, it seems to me that just trying to guess what's going wrong do no longer suffice and that you need extra info to debug.
Another possible way to solve this is to ask Bochs to enable the call trace (see bochs first aid kit in .:QuickLinkz:. for more info), so that you'll know what function/interrupt/exception calls are made.
At this level, it seems to me that just trying to guess what's going wrong do no longer suffice and that you need extra info to debug.
-
BI lazy
Re:having problems with printing messages
Hi, gosh!
You ask how to check what kind of Interrupt (exception/irq line): This is straight forward.
Take your usual isr stub and have it push a number on the stack *before* calling the c-isr. Afterwards you have to remove this value to some clobber register - say eax. it doesn't matter for the following popping will restore the former register values - maybe of another task.
Here is an example - in nasm and c.
I hope this helps to solve some problems.
stay safe
You ask how to check what kind of Interrupt (exception/irq line): This is straight forward.
Take your usual isr stub and have it push a number on the stack *before* calling the c-isr. Afterwards you have to remove this value to some clobber register - say eax. it doesn't matter for the following popping will restore the former register values - maybe of another task.
Here is an example - in nasm and c.
Code: Select all
in nasm define a macro like this one for your isr stubs.
%macro ISR 1 ;macro with one parameter
ISR_PROLOGUE ;macro for saving registers, pushing error codes etc.
push %1 ;put the parameter on the stack
call interrupt_handler ;to be defined as EXTERN!!!
pop eax ;remove the parameter from stack
ISR_EPILOGUE ;macro for restoring registers, removing error codes, etc
%endmacro
later in your code, where you place the isr and exception stubs in the code section (this is *the lowest level of kernel*!!)
you just say: ISR 1 ... ISR 31 -> for exceptions
ISR 31 ... ISR n -> for interrupt handlers.
for interrupt handlers, you can have different offsets in the IDT. Take care of that this is only an example.
In your C code for Interrupt handling, define the interrupt handlers like this:
void interrupt_handler(int irq);
And see, the parameter irq is pushed on the stack by the stub. Just pick it and check the number. Exceptions are only from 1 - 31 if i remember correctly.
stay safe
-
beyondsociety
Re:having problems with printing messages
When I enable the trace-on command, then set the virtual breakpoint to the loacation and then continue execution, it does an infinite loop. On the bochs manual it says once trace-on is entered, it will print every extruction on the cpu. How do I get it to just print the contents of a certain range of addresses?Another possible way to solve this is to ask Bochs to enable the call trace (see bochs first aid kit in .:QuickLinkz:. for more info), so that you'll know what function/interrupt/exception calls are made.