OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 5:12 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 35 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: problem with printing string !
PostPosted: Mon Nov 20, 2017 7:02 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
MichaelPetch wrote:
what is the file size of kernel.bin?


152 bytes


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

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
I don't know if it's a good idea, at least aesthetically, to post all the code here. But i'll do since it's not very long. Perhaps some one can give it a try (with MINGW please).
the boot sector source code: boot.asm
Code:
[ bits 16]
[org 0x7c00]
KERNEL_OFFSET equ 0x1000

mov [BOOT_DRIVE], dl   
mov bp, 0x9000
mov sp, bp

mov bx, MSG_REAL_MODE
call print_string

;load_kernel:
mov bx, MSG_LOAD_KERNEL
call print_string

mov bx, KERNEL_OFFSET
mov dh, 15
mov dl, [BOOT_DRIVE]
call disk_load
call switch_to_pm
jmp $

;==============
print_string:
   mov ah, 0x0e
loop:
   mov al, [bx]
   cmp al, 0
   je out
   int 0x10
   add bx, 0x01
   jmp loop
out:
   mov al, ' '
   int 0x10
   ret
;====================
disk_load:
   push dx
   mov ah, 0x02   
   mov al, dh   
   mov ch, 0x00   
   mov dh, 0x00      
   mov cl, 0x02
   int 0x13   
   jc disk_error
   pop dx
   cmp dh, al
   jne disk_error
   ret
disk_error:
   mov bx, [DISK_ERROR_MSG]
   call print_string
   jmp $

DISK_ERROR_MSG:
   db 'Disk read Error!', 0
;=======
switch_to_pm:
   cli   
   lgdt [gdt_descriptor]
   mov eax, cr0
   or eax, 0x1
   mov cr0, eax
   jmp CODE_SEG:init_pm

[bits 32]
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
   mov ebx, MSG_PROT_MODE
   call print_string_pm

   call KERNEL_OFFSET
   jmp $

;=================
VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f

print_string_pm:
   pusha
   mov edx, VIDEO_MEMORY
   print_string_pm_loop:
      mov al, [ebx]
      mov ah, WHITE_ON_BLACK
      cmp al, 0
      je done
      mov [edx], ax
      add edx, 2
      add ebx, 1
      jmp print_string_pm_loop
   done:
      popa
      ret
;===================
; GDT tabel
gdt_start:
   dd 0x0
   dd 0x0
gdt_code:
   dw 0xffff   
   dw 0x0      
   db 0x0      
   db 10011010b   
   db 11001111b   
   db 0x0      
gdt_data:
   dw 0xffff   
   dw 0x0      
   db 0x0      
   db 10010010b   
   db 11001111b   
   db 0x0      
gdt_end:   
gdt_descriptor:
   dw gdt_end - gdt_start - 1   
   dd gdt_start         

CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

BOOT_DRIVE:
   db 0
MSG_REAL_MODE:
   db " Started in 16- bit Real Mode ", 0
MSG_PROT_MODE:
   db " Successfully landed in 32- bit Protected Mode ", 0
MSG_LOAD_KERNEL:
   db " Loading kernel into memory. ", 0

times 510-($-$$) db 0
dw 0xaa55


the kernel entry point "kernel_entry.asm" :
Code:
[bits 32]
[extern _kmain]
call _kmain
jmp $

NOTE the underscore and the name of the main function it must be different than "main" else the linker will be unhappy!
The kernel source code "kernel.c":
Code:
void kmain(void)
{
   const char *str = "Hello World!!";
   char *vidmem = (char*)0xb8000;
   unsigned int i;
        // print char 'A' OK
   *vidmem ='A';
   *(vidmem+1) =0xA5;
   
       // first version to print the string NOT OK
   for(i=0;;i++){   
   if(str[i]==0) break;
   *vidmem =str[i];   
        *(vidmem+1) =0xA5;
          vidmem+=2;
   }
   
       // second version to print the string NOT OK
   while(*str != 0) {
      *vidmem= *str;
      vidmem+=2;
      str++;
   }

   // print char 'M' on the next line OK
   vidmem +=160;
   *vidmem ='M';
   *(vidmem+1) =0xA5;

   for(;;);
}


And last the makefile:
Code:
# Default make target
all: os.img

# Build the os image
os.img: boot.bin kernel.bin
   cat boot.bin kernel.bin > os.img

# Build the kernel binary
kernel.bin: kernel_entry.o kernel.o
   ld -T NUL -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o
   objcopy -O binary -j .text  kernel.tmp kernel.bin

# Build the kernel object file
kernel.O: kernel.C
   gcc -ffreestanding -c kernel.c -o kernel.o

# Build the kernel entry object file
kernel_entry.o: kernel_entry.asm
   nasm kernel_entry.asm -f elf -o kernel_entry.o

# Build the boot binary
boot.bin: boot.asm
   nasm -f bin -o boot.bin boot.asm

clean:
   rm -f *.o *.tmp *.bin


the command :
ld -o kernel.bin -Ttext 0x1000 kernel.o --oformat binary
didn't work for me !!


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

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
I've tested bochs with an image of retrounix and it works well.
So the suspect is MINGW.
I get the magic breakpoint working also. I must enable the option in the config file of the debugger (not the one for emulator) and use the debugger to start emulation.


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

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
MichaelPetch wrote:
Could you post the output of this command to humour me:

gcc -v


gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw32/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gmp-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)


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

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
MichaelPetch wrote:
Does this work by changing:
Code:
const char *str = "Hello world!";
to
Code:
const char str[] = "Hello world!";


YES this works !


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

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
I really APOLOGIZE I am deeply ashamed.
The mistake was in the makefile:

Code:
    objcopy -O binary -j .text  kernel.tmp kernel.bin

only the .text section is taken !!
I must delete the "-j .text" option to get all sections .
I copied the line as is from somewhere on the web without take care about every option in it

MANY thanks for all of you.


Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Mon Nov 20, 2017 2:13 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1925
Location: Athens, GA, USA
No need to apologize, really, this is the sort of thing that happens to everyone from time to time.

As for the aesthetics of posting the code, it isn't a problem for smaller sections, but for longer ones, we recommend giving a pointer to your offsite repo.

Let me back up a bit, and make a point which is, I hope, not really necessary. Do you have an offsite mirror of your version control repository on a host like CloudForge or GitHub?

Let me back up a bit more, just to be on the safe side: do you have your code under version control with a tool such as Subversion, Git, Bazaar, CVS, darcs, or Mercurial?

If not, then I strongly recommend getting it set up in one ASAP, and then find a suitable free host to keep a publicly accessible where you can keep a publicly-accessible mirror of the repo. Just sayin'. Trust me, you will definitely regret it if you don't have at least a local repository of your code, because sooner or later you are going to change something you didn't meant to, and will need to back your working copy up to a previous version.

That just the most basic use case for version control, but far from the only one - it isn't just about backups, its about managing change. You should still make regular backups of your files anyway, but version control goes beyond that.

Also, the public mirror not only serves as an additional backup copy of the repo, it allows you to show the code to others without having to explicitly post the code to a forum or send it as an attachment in an email.

Sorry for the digression, but I figured this was as good a point as any to mention this, and ask if you have that in hand already or not. Hopefully, you didn't even need this, but it's worth mentioning in case you didn't.

_________________
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 ! [SOLVED]
PostPosted: Mon Nov 20, 2017 3:09 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
Glad you got it working. So i essence by using -j text you excluded all the sections but .text including .rdata. I hope you undo the change I had you make to your code as an experiment.


Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Tue Nov 21, 2017 1:08 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
MichaelPetch wrote:
Glad you got it working.

Many thanks MichaelPetch again. Due to your suggestions I could fix the problem.
I've two more questions:
1- if I declare a global pointer to video ram I can't clear the screen or print the string:
Code:
char* videmem = (char*)0XB8000;
void clrsc(){
....
*vidmem = ' ';
...........
}
void print(char* str){
.....
*vidmem = *str;
........
}

2- the size of the binary file generated is big (about 12k bytes) !!
Opening it in HXD, it seems that the sections (.text .rdata ...) are 4096 bytes aligned.
Can we disable this alignement ?


Last edited by osdevnewbie on Tue Nov 21, 2017 1:19 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Tue Nov 21, 2017 1:14 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
Schol-R-LEA wrote:
Do you have an offsite mirror of your version control repository on a host like CloudForge or GitHub?

Alas, NO!
I think I'm not so "pro" to have a repo.
I'm only in the first steps. I'm still learning (despite my old age!!) :?


Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Tue Nov 21, 2017 6:00 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
Backing up Schol-R-LEA here.

If you don't have a repository / version control software...

  • ...you have no way to trace back when you made which change, and what you were thinking when you made it (commit messages!)
  • ...you have no way to "undo" a change when you later find it was ill-advised
  • ...your project source code can be utterly and irrevocably wiped out with a single, careless, delete operation

If at all possible, keep the repository (or regular backups thereof) on a different computer. Hard drives can die, computers can get stolen, and you don't want your project to just go "poof" when (not if) that happens.

Getting an account with one of the free VCS hosters out there is easy enough. If you cannot / do not want to do this, note that many fileservers offer similar functionality for a comparably small price.

Personally, I've set up my home network so that *everything* is stored on a RAID-1 server (Synology DiskStation), with source code additionally kept in a SVN repo on the disk station and being backed up to cloud storage once a week.

Call it paranoid, but I couldn't care less if a hard drive dies, even in the disk station. Get a new one and get going again.

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Tue Nov 21, 2017 8:23 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
@ Schol-R-LEA, @solar
No one can deny the pros of a repo. Just at the moment I'm not doing an interesting work that worth it !!
I save always a copy of my work on an external hard disk. Who knows.
Many thanks for the advice any way


Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Tue Nov 21, 2017 8:41 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
If your code is interesting enough that you ask others to spend their time helping you with it then it is surely interesting enough for you to preserve it safely, with the ability to revert to previous versions.

Setting up a git repository is trivial.


Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Tue Nov 21, 2017 8:15 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
On Windows if you use NUL as a script it doesn't alter the default Linker rules (Cygwin/MinGW LD) for sections that aren't processed in the script. Each section will potentially be aligned to 4kb boundairies when dealing with Windows PE objects. Since you have chosen not to use a cross compiler you'll have to use parameters specific to the LD (linker) for that platform. In particular if you want to reduce code since and get rid of the 4kb you can use this:
Code:
ld -nostdlib -T NUL --file-alignment 0 --section-alignment 32 -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o
I highly recommend (insist) you use -nostdlib to explicitly tell LD that no standard library code will be used. --file-alignment 0 --section-alignment 32
will align each section to a 32-byte boundary. Doing a man ld will give you more details of these two parameters.

The reason your code started to break when you moved the vidmem to global scope is that it was placed in the data section, and that would have added an additional 4kb to your kernel. Since you only load 15 sectors (of 512 bytes each) for the kernel that will exclude anything beyond from byte 7680 (15*512) onward. Your `vidmem` pointer likely fell outside the kernel you were loading and thus not initialized to 0xb8000 .

I noticed an issue in your Makefile. You have this:
Code:
kernel.O: kernel.C
Case matters here I believe you want
Code:
kernel.o: kernel.c
. The way you have it would produce kernel.o from kernel.c using the default Make rules.


Top
 Profile  
 
 Post subject: Re: problem with printing string ! [SOLVED]
PostPosted: Wed Nov 22, 2017 2:32 am 
Offline
Member
Member

Joined: Sat Mar 26, 2016 1:25 pm
Posts: 36
iansjack wrote:
If your code is interesting enough that you ask others to spend their time helping you with it

I've sincerely apologized for wasting your precious time.
when I said "not interesting" I meant for other people, cause I'm following a guide posted on the web since a long time, so there's no NEW thing I've done.
For me of course it's very very interesting.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 69 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