I have a custom bootloader
booting into a custom kernel. I'm writing in C now the assembly is out of the way.
So far, local variables and methods work fine, but global variables aren't being recognized when it's compiled and ran.
I have these three functions:
void SetChar(int VidIndex, char c) { //Print a single char to a mem index set by VidIndex : WORKS!!
char* vidPtr = (char*)0xb8000;
vidPtr += VidIndex * 2;
*vidPtr = c;
}
void PrintString(char* string) { //Print 20 chars of a string, as a test : NOT WORKS
char* ptr = string;
for (int t = 0; t < 20; t++) {
SetChar(t, *ptr);
ptr++;
}
}
void ClearScreen() { //Sets all chars in Video Memory to empty : WORKS!!
for (char* ptr = (char*)0xb8000; ptr < (char*)(0xb8000 + 4000); ptr+=0x02) {
*ptr = ' ';
}
}
Using a main function such as this works fine and does what I want it to:
void _main() {
ClearScreen();
SetChar(5, 'H');
SetChar(6, 'e');
SetChar(7, 'l');
SetChar(8, 'l');
SetChar(9, 'o');
return ;
}
However, If I do this:
char* WelcomeString = "Welcome to my 32 bit OS with a C kernel.";
void _main() {
ClearScreen();
PrintString(WelcomeString);
return ;
}
Then the image is completely black with nothing on it. Looking at the binary data reveals that the char* bytes aren't compiled in to it. This doesn't work with other global variables either. I am compiling and linking in a .bat like so:
nasm "C:\Users\Braiden\source\repos\Operating System\Bootloader.asm" -o bootloader.bin -f bin -i "C:\Users\Braiden\source\repos\Operating System"
nasm "C:\Users\Braiden\source\repos\Operating System\kernel_entry.asm" -f elf64 -o kernel_entry.o
nasm "C:\Users\Braiden\source\repos\Operating System\padding.asm" -o padding.bin -f bin
gcc -ffreestanding -c "C:\Users\Braiden\source\repos\Operating System\Kernel.c" -o kernel.o
ld -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o
objcopy -O binary -j .text kernel.tmp kernel.bin
copy /b bootloader.bin+kernel.bin+padding.bin os-image.img
pause
What could be the reason that it is acting this way? It is very strange to me. I'm willing to provide more information if needed. I'm just not sure what I need to provide.
Edit: Bootloader.asm
global _start
_start:
[bits 16]
[org 0x7c00]
KERNEL_ENTRY equ 0x1000
mov bp, 0x8000
mov sp, bp
mov bx, welcomeString
call print_func
mov [ BOOT_DRIVE ], dl ; BIOS stores our boot drive in DL , so it ’s
; best to remember this for later.
mov bp, 0x7c00 ; Here we set our stack safely out of the
mov sp, bp ; way , at 0 x8000
mov bx, KERNEL_ENTRY ; Load 5 sectors to 0x0000 (es):KERNEL_ENTRY (bx)
mov dh, 41 ; from the boot disk.
mov dl, [ BOOT_DRIVE ]
call ReadDisk
mov bx, readSuccessString ; Print Success after reading disk
call print_func
mov bx, 0x7e00 ; Let's see if we loaded the area
call print_hex_func ; correctly
call print_newline_func
call PrintAddress
call print_newline_func
jmp switch_to_pm
jmp $
%include "io.asm"
%include "print.asm"
%include "gdt.asm"
welcomeString:
db 'Hello. Welcome to OS', 13, 10,0
readSuccessString:
db 'Disk read Success', 13, 10, 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
jmp BEGIN_PM
BEGIN_PM:
jmp KERNEL_ENTRY ; jump out of our 512 byte sector into the rest of our loaded memory
; so we have much more space to work, and start the kernel
jmp $
MSG_PM:
db 'success', 0
times 510-($-$$) db 0
dw 0xaa55
kernel_entry.asm
[bits 32]
[extern _main]
call _main
jmp $
gcc -v output: (Using MinGW)
Using built-in specs.
COLLECT_GCC=C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin\gcc.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
COLLECT_GCC_OPTIONS='-v' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=core2' '-march=nocona'
C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/cc1.exe -quiet -v -iprefix C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/ -D_REENTRANT C:\Users\Braiden\source\repos\Operating System\Kernel.c -quiet -dumpbase Kernel.c -mtune=core2 -march=nocona -auxbase-strip kernel.o -version -ffreestanding -o C:\Users\Braiden\AppData\Local\Temp\ccTxrZFP.s
GNU C17 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) version 8.1.0 (x86_64-w64-mingw32)
compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/8.1.0/include"
ignoring nonexistent directory "C:/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../include"
ignoring duplicate directory "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed"
ignoring duplicate directory "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "C:/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include
C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed
C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include
End of search list.
GNU C17 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) version 8.1.0 (x86_64-w64-mingw32)
compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 985ce7ae6dd3a696cd146ca9896b0035
COLLECT_GCC_OPTIONS='-v' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=core2' '-march=nocona'
C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/as.exe -v -o kernel.o C:\Users\Braiden\AppData\Local\Temp\ccTxrZFP.s
GNU assembler version 2.30 (x86_64-w64-mingw32) using BFD version (GNU Binutils) 2.30
COMPILER_PATH=C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../libexec/gcc/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../lib/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../
COLLECT_GCC_OPTIONS='-v' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=core2' '-march=nocona'
objdump -x kernel.tmp
kernel.tmp: file format pei-x86-64
kernel.tmp
architecture: i386:x86-64, flags 0x00000132:
EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x0000000100001000
Characteristics 0x227
relocations stripped
executable
line numbers stripped
large address aware
debugging information removed
Time/Date Sun Jun 21 02:05:38 2020
Magic 020b (PE32+)
MajorLinkerVersion 2
MinorLinkerVersion 30
SizeOfCode 00000200
SizeOfInitializedData 00000a00
SizeOfUninitializedData 00000000
AddressOfEntryPoint 00000000ffc01000
BaseOfCode 00000000ffc01000
ImageBase 0000000000400000
SectionAlignment 0000000000001000
FileAlignment 0000000000000200
MajorOSystemVersion 4
MinorOSystemVersion 0
MajorImageVersion 0
MinorImageVersion 0
MajorSubsystemVersion 5
MinorSubsystemVersion 2
Win32Version 00000000
SizeOfImage ffc07000
SizeOfHeaders 00000400
CheckSum 00006de2
Subsystem 00000003 (Windows CUI)
DllCharacteristics 00000000
SizeOfStackReserve 0000000000200000
SizeOfStackCommit 0000000000001000
SizeOfHeapReserve 0000000000100000
SizeOfHeapCommit 0000000000001000
LoaderFlags 00000000
NumberOfRvaAndSizes 00000010
The Data Directory
Entry 0 0000000000000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000ffc06000 00000014 Import Directory [parts of .idata]
Entry 2 0000000000000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000ffc04000 00000030 Exception Directory [.pdata]
Entry 4 0000000000000000 00000000 Security Directory
Entry 5 0000000000000000 00000000 Base Relocation Directory [.reloc]
Entry 6 0000000000000000 00000000 Debug Directory
Entry 7 0000000000000000 00000000 Description Directory
Entry 8 0000000000000000 00000000 Special Directory
Entry 9 0000000000000000 00000000 Thread Storage Directory [.tls]
Entry a 0000000000000000 00000000 Load Configuration Directory
Entry b 0000000000000000 00000000 Bound Import Directory
Entry c 0000000000000000 00000000 Import Address Table Directory
Entry d 0000000000000000 00000000 Delay Import Directory
Entry e 0000000000000000 00000000 CLR Runtime Header
Entry f 0000000000000000 00000000 Reserved
There is an import table in .idata at 0x6000
The Import Tables (interpreted .idata section contents)
vma: Hint Time Forward DLL First
Table Stamp Chain Name Thunk
ffc06000 00000000 00000000 00000000 00000000 00000000
The Function Table (interpreted .pdata section contents)
vma: BeginAddress EndAddress UnwindData
0000000100004000: 0000000100001010 0000000100001044 0000000100005000
has negative begin address
has negative end address
has negative unwind address
000000010000400c: 0000000100001044 000000010000108b 000000010000500c
has negative begin address
has negative end address
has negative unwind address
0000000100004018: 000000010000108b 00000001000010ba 0000000100005018
has negative begin address
has negative end address
has negative unwind address
0000000100004024: 00000001000010ba 00000001000010dd 0000000100005024
has negative begin address
has negative end address
has negative unwind address
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000100 0000000100001000 0000000100001000 00000400 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000010 0000000100002000 0000000100002000 00000600 2**4
CONTENTS, ALLOC, LOAD, DATA
2 .rdata 00000070 0000000100003000 0000000100003000 00000800 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .pdata 00000030 0000000100004000 0000000100004000 00000a00 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .xdata 00000030 0000000100005000 0000000100005000 00000c00 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .idata 00000014 0000000100006000 0000000100006000 00000e00 2**2
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[ 0](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x0000000000000013 Kernel.c
File
[ 2](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 1) 0x0000000000000010 SetChar
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 4](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x0000000000000044 PrintString
[ 5](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x000000000000008b ClearScreen
[ 6](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000000000ba _main
[ 7](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000010 .text
AUX scnlen 0xcd nreloc 1 nlnno 0
[ 9](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .data
AUX scnlen 0x8 nreloc 1 nlnno 0
[ 11](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .xdata
AUX scnlen 0x30 nreloc 0 nlnno 0
[ 13](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .pdata
AUX scnlen 0x30 nreloc 12 nlnno 0
[ 15](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000000 .rdata
AUX scnlen 0x29 nreloc 0 nlnno 0
[ 17](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000030 .rdata$zzz
AUX scnlen 0x3f nreloc 0 nlnno 0
[ 19](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x0000000000000015 C:\Users\Braiden\source\repos\Operating System\kernel_entry.asm
File
[ 21](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000070 ___RUNTIME_PSEUDO_RELOC_LIST__
[ 22](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __data_start__
[ 23](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000000000f0 ___DTOR_LIST__
[ 24](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___tls_start__
[ 25](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000400000 __ImageBase
[ 26](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000070 __rt_psrelocs_start
[ 27](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __dll_characteristics__
[ 28](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 __size_of_stack_commit__
[ 29](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000200000 __size_of_stack_reserve__
[ 30](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000005 __major_subsystem_version__
[ 31](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xl_start__
[ 32](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xi_start__
[ 33](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xi_end__
[ 34](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __bss_start__
[ 35](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000070 ___RUNTIME_PSEUDO_RELOC_LIST_END__
[ 36](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 __size_of_heap_commit__
[ 37](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xp_start__
[ 38](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xp_end__
[ 39](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __dll__
[ 40](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __minor_os_version__
[ 41](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000400000 __image_base__
[ 42](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 __section_alignment__
[ 43](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000014 __IAT_end__
[ 44](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000070 __RUNTIME_PSEUDO_RELOC_LIST__
[ 45](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 WelcomeString
[ 46](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000010 __data_end__
[ 47](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000000000e0 __CTOR_LIST__
[ 48](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __bss_end__
[ 49](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xc_end__
[ 50](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xc_start__
[ 51](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000000000e0 ___CTOR_LIST__
[ 52](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __rt_psrelocs_size
[ 53](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000200 __file_alignment__
[ 54](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000004 __major_os_version__
[ 55](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000014 __IAT_start__
[ 56](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 __end__
[ 57](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000000000f0 __DTOR_LIST__
[ 58](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000100000 __size_of_heap_reserve__
[ 59](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xt_start__
[ 60](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000003 __subsystem__
[ 61](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___tls_end__
[ 62](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __major_image_version__
[ 63](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __loader_flags__
[ 64](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000070 __rt_psrelocs_end
[ 65](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000002 __minor_subsystem_version__
[ 66](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000000 __minor_image_version__
[ 67](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000000070 __RUNTIME_PSEUDO_RELOC_LIST_END__
[ 68](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000000001000 ___crt_xt_end__
Make sure your custom bootloader is reading in the entire kernel. Have you read enough sectors to make sure the entire kernel is in memory?. The one problem that stands out to me that I can identify in what you have shown is in how you are generating kernel.bin
. You do:
objcopy -O binary -j .text kernel.tmp kernel.bin
This only places the .text
section (code) into kernel.bin
and nothing else. Your string that isn't printing is likely in the .rdata*
sections which you have neglected to include in the kernel. I would include all the sections with:
objcopy -O binary kernel.tmp kernel.bin
This seems to be related to another recent now deleted SO question that was very similar and cross posted to the OSDev Forum. The problem there appears to be the same one here.
The original question was amended by request with additional details. The number of sectors being read was not enough to cover the size of the kernel.
Another issue was identified. The compiler is a 64-bit MinGW Windows compiler; the bootloader only puts the processor in 32-bit protected mode; and the code generated is 64-bit code. You can't properly run 64-bit code in 32-bit protected mode. The code may partially run correctly but it will eventually exhibit unusual and unwanted behaviour.
The choices you have are to put the processor in 64-bit long mode as part of your custom bootloader or have your compiler, assembler, and linker generate 32-bit objects and executables. I touch on this issue in another related Stackoverflow Answer.
You can change nasm to use -felf32
to assemble to 32-bit objects. Since you are using Windows native GCC compilers you can also use -fwin32
. To compile GCC code as 32-bit you can use -m32
option and the linker (ld
) requires the -mi386pe
option. Another option you may wish to use with linking when it comes to OSDev with Windows compilers is LD's -N
option which is defined as:
-N, --omagic Do not page align data, do not make text readonly
With all that being said, you can save yourself many hassles by using an i386 or i686 ELF cross compiler if generating 32-bit code and a 64-bit ELF cross compiler if targeting 64-bit code for OS development. More information on building/using Windows Cross compilers can be found in this tutorial and the OSDev wiki has a section on GCC cross compilers in general.
If generating 32-bit Windows objects and executables the non static functions at global scope require an _
to be prepended to them. These underscores are automatically generated by GCC but must be added when you reference them from assembly code. Same applies to assembly functions you create that will be called from C code. You will get an undefined reference if you compile and assemble your code because you declare main
this way:
void _main() {
The GCC MinGW compiler will append an underscore to the beginning and the function will be named __main
. You would need amend the assembly code to use __main
instead of _main
as your code currently does. But even easier is to change the declaration to:
void main() {
This will generate a function called _main
and that is the function name your assembly code is currently expecting.
64-bit Windows objects and executables do not require or generate functions at global scope with a prefix of _
. That is why this isn't an issue when you were generating the 64-bit code.
I'd been compiling 64 bit binaries, while I booted into 32 bit protected mode. Compiling and linking them in 32 bit fixed the issue. This raised another issue with the external function prefix "_", which was fixed by just updating the method name so that the prefix didn't cause issues.
my final compile and linking commands:
nasm "C:\Users\Braiden\source\repos\Operating System\Bootloader.asm" -o bootloader.bin -f bin -i "C:\Users\Braiden\source\repos\Operating System"
nasm "C:\Users\Braiden\source\repos\Operating System\kernel_entry.asm" -f elf32 -o kernel_entry.o
nasm "C:\Users\Braiden\source\repos\Operating System\padding.asm" -o padding.bin -f bin
gcc -ffreestanding -m32 -c "C:\Users\Braiden\source\repos\Operating System\Kernel.c" -o kernel.o
ld -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o -mi386pe
objcopy -O binary kernel.tmp kernel.bin
copy /b bootloader.bin+kernel.bin+padding.bin os-image.img
User contributions licensed under CC BY-SA 3.0