OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 3:54 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: problem with printing string ! [SOLVED]
PostPosted: Sat Nov 18, 2017 12:13 pm 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
EDIT: the mistake was in the makefile

Hi all,
I'm following Blundell's guide to write a simple OS.
The bootsector works as a charm. In the kernel I can clear the screen and print characters individually, but when I want to print a string I get only the letter "A" !!
I'm working under WIN and using nasm, mingw and bochs .

Code:
void kmain(void)
{
   const char *str = "Hello world!";
   char *vidmem = (char*)0xb8000;    
   unsigned int i = 0;
   unsigned int j = 0;

   // clear screen OK
   while(j < 80 * 25 * 2) {
      vidmem[j] = ' ';
      vidmem[j+1] = 0x07;       
      j = j + 2;
   }
     
      // print a character OK
       j=0;
       vidmem[j] = 'A';
       vidmem[j+1] = 0x07;
 
       // print a string :  this part don't work !!!!
   j = 0;
   while(str[j] != '\0') {
      vidmem[i] = str[j];
      vidmem[i+1] = 0x07;
      ++j;
      i = i + 2;
   }
   return;
}

Many thanks in advance.


Last edited by osdevnewbie on Mon Nov 20, 2017 11:31 am, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sat Nov 18, 2017 12:27 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
1. Examine the generated code. Does it use the "movs" instruction?

2. Have you set DS and ES registers?

3. Single-step the code under a debugger to see what is happening.


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sat Nov 18, 2017 12:35 pm 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
iansjack wrote:
2. Have you set DS and ES registers?


Thanks iansjack for the quick reply !!
DS and ES are set in the bootsector:
Code:
[bits 32]
; Initialise registers and the stack once in PM.
init_pm :
  mov ax , DATA_SEG   
  mov ds , ax         
  mov ss , ax         
  mov es , ax
  mov fs , ax
  mov gs , ax
  mov ebp , 0x90000   
  mov esp , ebp         


where DATA_SEG =0x10 (3rd entry in the GDT).


Last edited by osdevnewbie on Sat Nov 18, 2017 12:46 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sat Nov 18, 2017 12:40 pm 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
iansjack wrote:
1. Examine the generated code. Does it use the "movs" instruction?


I've examined the code:
gcc -S kernel.c

there's no "movs" instruction, only movl, movb.


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sat Nov 18, 2017 1:30 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

osdevnewbie wrote:
The bootsector works as a charm. In the kernel I can clear the screen and print characters individually, but when I want to print a string I get only the letter "A" !!
I'm working under WIN and using nasm, mingw and bochs .


What does it do instead of printing the rest of the string?

Does it return from "kmain()" (e.g. because the kernel wasn't loaded properly and the string was truncated)? Does it crash (e.g. because an IRQ occurred just after the "A" was printed)? Does it do something else (e.g. execute a lot of addition instructions because the CPU Is executing zeros/garbage)?

Note: There were at least some versions of one of the emulators (can't remember if it was Bochs or Qemu, and I'm not sure if it was fixed or not); where it'd use emulated video display memory to update the emulator's window on the host after emulating a specific number of instructions (e.g. "every 100000 emulated instructions update the output window"); and where if you do a "HLT" instruction with IRQs disabled it didn't emulate more instructions, so the "number of instructions emulated" counter didn't increase, so it doesn't update the output window anymore. In this case the code might correctly print the first character; then the emulator might update its output window; then the code might correctly print the remainder of the string, return from "kmain()" and then do "HLT" with IRQs disabled - the remainder of the string would have been printed correctly, but would never be seen in the emulator's output window.

I'm also wondering if your copy of Bochs has been compiled with all the nice debugging options. If it has; you should be able to put a breakpoint immediately before the loop that prints the string and single-step one instruction at a time, and figure out exactly what is going wrong where.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sat Nov 18, 2017 2:55 pm 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
Brendan wrote:
What does it do instead of printing the rest of the string?

Thanks Brendan for the long response.
In fact I'm new to bochs, it seems that it halted cause there's no output in boxhs's console.
in the bootsector there's an infinite loop after calling the kernel code:
Code:
  call KERNEL_OFFSET       
  jmp $                   


I tried a break point in the code and added :
magic_break: enabled=1
in bochs's config file but it did'nt stop:
Code:
   while(j < 80 * 25 * 2) {
      /* blank character */
      vidptr[j] = ' ';
      /* attribute-byte - light grey on black screen */
      vidptr[j+1] = 0x07;       
      j = j + 2;
   }
   
   //magic break point
  asm  volatile ("xchgw %bx, %bx");
 
   j = 0;
   vidptr[j] = 'A';
  vidptr[j+1] = 0x07;


I'm reading more about debugging with bochs.


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sat Nov 18, 2017 3:04 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

osdevnewbie wrote:
I tried a break point in the code and added :
magic_break: enabled=1
in bochs's config file but it did'nt stop:


I suspect that you've downloaded a pre-compiled "Bochs for Windows" where most of the debugging stuff was disabled at compile time.

In that case; it'd probably be best to download the Bochs source code, then configure and compile it yourself, so that you can enable support for all the debugging (and whatever other features you do/don't want).


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sun Nov 19, 2017 1:45 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
I hope you aren't compiling the C code as 64-bit code and running it in 32-bit protected mode.


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sun Nov 19, 2017 2:39 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
Brendan wrote:
I suspect that you've downloaded a pre-compiled "Bochs for Windows" where most of the debugging stuff was disabled at compile time.

Yes, perhaps.
I'll try to build bochs from sources.
Thanks again


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sun Nov 19, 2017 2:41 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
MichaelPetch wrote:
I hope you aren't compiling the C code as 64-bit code and running it in 32-bit protected mode.

Thanks MichaelPetch.
I'm on a 32bit system with 32bit win xp.
I don't think that default gcc output is a 64bit file !!


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sun Nov 19, 2017 10:51 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
Could you post the output of this command to humour me:

gcc -v


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sun Nov 19, 2017 10:56 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
One guess I have though is that you possibly aren't reading all of your kernel into memory and the read only data section containing your string is not in memory so it doesn't print anything. Verify in your bootloader that you are reading enough sectors of the disk to read your entire kernel into memory.

A test to see if you can print a string from a loop would to be to place it on the stack as an experiment. Does this work by changing:
Code:
const char *str = "Hello world!";
to
Code:
const char str[] = "Hello world!";
. This change should have the effect of the string being generated on the stack rather than placed in the read only section of the kernel. This isn't meant as a fix, but a simple experiment. If the program works with this change then I highly suspect you have a problem with the read only section not being in memory for some reason.


Last edited by MichaelPetch on Sun Nov 19, 2017 9:08 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Sun Nov 19, 2017 12:03 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1925
Location: Athens, GA, USA
Apropos of @MichaelPetch's question: how are you preparing the C executable, in what form or format is it stored in the disk image, and how are you loading it? Are you converting it to a raw binary image, or is it loading it from an executable in a standard Executable Format such as ELF or PE?

I am not particularly familiar with the tutorial you mention, but a quick review of the PDF tells me that it is converting the executable to raw binary, so am assuming that this is the procedure you are following.

I should point out that while this does look like a pretty solid tutorial, you should keep in mind that no tutorial is flawless, and most tutorials have long-standing, known bugs which don't always get fixed. Also, while most of the things they apply remain stable for years, things do grow out of date with time. You need to apply any tutorial thoughtfully, and while you do seem to be doing so, it is always worth reminding people of this - especially when the tutorial is, for the most part, a good one, as it is all too easy to get used to assuming that the tutorial will remain correct.

Trust me, I am speaking from personal experience on this, having made that mistake all too many times myself.

On a somewhat related note, have you prepared a separate GCC Cross-Compiler and cross-development OS-Specific Toolchain, separate from any tools targeting your development host (which you state is 32-bit Windows XP)? Again, not being familiar with the tutorial, I can't be sure, but it looks it isn't something it discusses. While it is possible to work without doing that - as the part that does seem to work shows - using a cross-compiler solves a lot of the problems with doing that, as does using a build tool such as Make rather than running the compiler on the command line directly.

You probably should keep following the process as given, to avoid confusion for now, but be aware that in later development you probably should set up a cross-compiler.

One other thing, though this is just a stylistic question: why are you using while() loops for definite loops instead of for()? For example, rather than:

Code:
   while(j < 80 * 25 * 2) {
      vidmem[j] = ' ';
      vidmem[j+1] = 0x07;       
      j = j + 2;
   }


you could use

Code:
const unsigned int rows = 25, columns = 80;
const unsigned int vidbuf_size = rows * columns * 2;

   unsigned int j = 0;

   for (j = 0; j < vidbuf_size; j += 2) {
      vidmem[j] = ' ';
      vidmem[j+1] = 0x07;
   }


This makes it clearer that the intent is to walk through a fixed number of iterations - what is called a 'definite iteration' - which is the main purpose of for(). The while() loop, conversely, is usually used for indefinite loops, where the number of passes is determined by something in the loop body rather than the loop conditionals.

I am not saying the code was wrong - it does clearly work - but it isn't really idiomatic in C to use while() for that. I was just wondering if there was a specific reason why you were doing it that way.

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Mon Nov 20, 2017 1:26 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
Many thanks Schol-R-LEA and MichaelPetch for your replys, I'll try your solutions and post feedback soon.
The disk image is in binary format :
Code:
     cat boot.bin kernel.bin > os.img

so the kernel code is on the 2nd sector on the disk.
the boot loads 15 sectors from the disk (starting from 2nd sector).


Top
 Profile  
 
 Post subject: Re: problem with printing string !
PostPosted: Mon Nov 20, 2017 2:07 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
osdevnewbie wrote:
Code:
     cat boot.bin kernel.bin > os.img

so the kernel code is on the 2nd sector on the disk.
the boot loads 15 sectors from the disk (starting from 2nd sector).
If you do a directory listing what is the file size of kernel.bin?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 59 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group