152 bytesMichaelPetch wrote: what is the file size of kernel.bin?
problem with printing string ! [SOLVED]
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string !
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string !
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
the kernel entry point "kernel_entry.asm" :
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":
And last the makefile:
the command :
ld -o kernel.bin -Ttext 0x1000 kernel.o --oformat binary
didn't work for me !!
the boot sector source code: boot.asm
Code: Select all
[ 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
Code: Select all
[bits 32]
[extern _kmain]
call _kmain
jmp $
The kernel source code "kernel.c":
Code: Select all
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(;;);
}
Code: Select all
# 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
ld -o kernel.bin -Ttext 0x1000 kernel.o --oformat binary
didn't work for me !!
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string !
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.
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.
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string !
gcc -vMichaelPetch wrote:Could you post the output of this command to humour me:
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)
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string !
YES this works !MichaelPetch wrote: Does this work by changing:toCode: Select all
const char *str = "Hello world!";
Code: Select all
const char str[] = "Hello world!";
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string !
I really APOLOGIZE I am deeply ashamed.
The mistake was in the makefile:
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.
The mistake was in the makefile:
Code: Select all
objcopy -O binary -j .text kernel.tmp kernel.bin
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.
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: problem with printing string ! [SOLVED]
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.
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.
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.
-
- Member
- Posts: 799
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: problem with printing string ! [SOLVED]
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.
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string ! [SOLVED]
Many thanks MichaelPetch again. Due to your suggestions I could fix the problem.MichaelPetch wrote:Glad you got it working.
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: Select all
char* videmem = (char*)0XB8000;
void clrsc(){
....
*vidmem = ' ';
...........
}
void print(char* str){
.....
*vidmem = *str;
........
}
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.
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string ! [SOLVED]
Alas, NO!Schol-R-LEA wrote:Do you have an offsite mirror of your version control repository on a host like CloudForge or GitHub?
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!!)
Re: problem with printing string ! [SOLVED]
Backing up Schol-R-LEA here.
If you don't have a repository / version control software...
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.
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
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.
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string ! [SOLVED]
@ 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
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
Re: problem with printing string ! [SOLVED]
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.
Setting up a git repository is trivial.
-
- Member
- Posts: 799
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: problem with printing string ! [SOLVED]
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: 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: Case matters here I believe you want . The way you have it would produce kernel.o from kernel.c using the default Make rules.
Code: Select all
ld -nostdlib -T NUL --file-alignment 0 --section-alignment 32 -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o
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: Select all
kernel.O: kernel.C
Code: Select all
kernel.o: kernel.c
-
- Member
- Posts: 36
- Joined: Sat Mar 26, 2016 1:25 pm
Re: problem with printing string ! [SOLVED]
I've sincerely apologized for wasting your precious time.iansjack wrote:If your code is interesting enough that you ask others to spend their time helping you with it
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.