OSDev.org

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

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: BOOTBOOT kernel example not working
PostPosted: Tue Apr 28, 2020 12:19 pm 
Offline

Joined: Tue Apr 28, 2020 11:54 am
Posts: 3
I am trying to setup the example kernel provided by @bzt on the official documentation page but the kernel does not print anything to the screen. Not sure if I haven't configured something correctly, or if I am doing something completely wrong.
The bootloader seems to be working correctly because I see the initialization functions being called on the vm.

I've been testing it by adding code by parts to see what is not working but seems like the framebuffer is not responding.
I modified the provided makefile to work with my particular setup.
I am using a x86_64-elf cross compiler made by following the wiki with no red zone enabled.

If you want to check out my progress and point me in the right direction you can go here https://github.com/gerarparra0/osdev64
Excuse my poor makefile skillz, I'm pretty new at this :oops:


Top
 Profile  
 
 Post subject: Re: BOOTBOOT kernel example not working
PostPosted: Sun May 03, 2020 8:22 am 
Offline

Joined: Sat Jun 08, 2019 4:36 am
Posts: 4
Your kernel boots and prints a cross-hair and a red square. I used the following:

Code:
# bootboot with GNU parted and FAT16
set -v # Print commands
set -e  # Stop on first error
(cd mykernel && make mykernel.x86_64.elf)
mkdir -p initrd/sys
cp mykernel/mykernel.x86_64.elf initrd/sys/core
(cd initrd && find . | cpio -H newc -o > ../INITRD)
(cd x86_64-bios && make mkboot)
dd if=/dev/zero of=bios.img bs=512 count=93750
parted bios.img mklabel gpt
parted bios.img mkpart primary fat16 2048s 100%
parted bios.img set 1 boot on
sudo losetup --offset 1048576 --sizelimit 46934528 /dev/loop0 bios.img
sudo mkfs.fat -F 16 /dev/loop0p1
sudo mount /dev/loop0p1 /mnt/data
sudo mkdir /mnt/data/BOOTBOOT
sudo cp bootboot.bin /mnt/data/BOOTBOOT/LOADER
sudo cp INITRD /mnt/data/BOOTBOOT/
sudo umount /mnt/data
sudo losetup -d /dev/loop0
./x86_64-bios/mkboot bios.img
export NUMCORES=4
echo "Starting qemu with $NUMCORES cores"
qemu-system-x86_64 -smp "$NUMCORES" -net none -hda bios.img


Top
 Profile  
 
 Post subject: Re: BOOTBOOT kernel example not working
PostPosted: Mon May 04, 2020 8:43 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
gerarparra0 wrote:
I am trying to setup the example kernel provided by @bzt on the official documentation page but the kernel does not print anything to the screen.
Can you see the cross-hair? Or the R/G/B boxes? Is it only the string printing that's not working, or is it all blank? (All blank => framebuffer initialization error probably; cross-hair ok, but printing isn't => could be font linking issue, linker script misconfiguration and also many other things in your kernel.)

In lack of a framebuffer, the serial console is also initialized and configured to 115200 baud, 8 data bits, 1 stop bit, no parity, so you can print to the vm's console (for qemu, use "-serial stdio" command line argument, and you should see the text you send in your guest OS on the terminal in which you started qemu). With bochs, you can also use the "e9 hack" (when you enable that, then you can write characters to the bochs' terminal simply by using "out al, 0xe9").

This is what I use:
Code:
    unsigned char chrtoprint = 'A';
    asm volatile(
        "xorl %%ebx, %%ebx; movb %0, %%bl;"
#ifdef BOCHS
        // bochs e9 port hack
        "movb %%bl, %%al;outb %%al, $0xe9;"
#endif
        // print character on serial
        "movl $10000,%%ecx;movw $0x3fd,%%dx;"
        // transmit buffer ready?
        "1:inb %%dx, %%al;"
        "cmpb $0xff,%%al;je 2f;"
        "dec %%ecx;jz 2f;"
        "andb $0x20,%%al;jz 1b;"
        // send out character
        "subb $5,%%dl;movb %%bl, %%al;outb %%al, %%dx;2:"
    ::"r"(chrtoprint));
NOTE: On UEFI, the serial console is NOT initialized by default, you have to go to your UEFI manager's configuration and enable console (ConIn/ConOut) on serial feature manually. After that it will work in your kernel too. (You could also initialize the serial yourself, inline assembly example).

gerarparra0 wrote:
I've been testing it by adding code by parts to see what is not working but seems like the framebuffer is not responding.
Which version are you using? And which boot mechanism (RPi/x86 BIOS/x86 UEFI/Multiboot/El Torito...etc.)? Did it work before you added your code parts?

gerarparra0 wrote:
Excuse my poor makefile skillz, I'm pretty new at this :oops:
In the images folder you can find an example makefile to generate bootable disk images (along with a very simple mkimg.c image creator tool). First you should test your vm configuration with the sample disk images I provided.

I suggest to follow these steps to narrow down where the problem might be located:
1. run a provided image in your vm - this will test your execution environment. If this isn't okay, then check your vm's configuration.
2. try to create an image of your own with the example mykernel - this will test your build environment.
3. replace the example kernel and makefile with your own - if the error happens when you do so, then the problem is with your source.

Go to each step only when the previous steps are ok. If you can tell me at which step your problem appears, I'll be able to help more.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: BOOTBOOT kernel example not working
PostPosted: Mon May 04, 2020 10:45 am 
Offline

Joined: Tue Apr 28, 2020 11:54 am
Posts: 3
bzt wrote:
gerarparra0 wrote:
I am trying to setup the example kernel provided by @bzt on the official documentation page but the kernel does not print anything to the screen.
Can you see the cross-hair? Or the R/G/B boxes? Is it only the string printing that's not working, or is it all blank? (All blank => framebuffer initialization error probably; cross-hair ok, but printing isn't => could be font linking issue, linker script misconfiguration and also many other things in your kernel.)

In lack of a framebuffer, the serial console is also initialized and configured to 115200 baud, 8 data bits, 1 stop bit, no parity, so you can print to the vm's console (for qemu, use "-serial stdio" command line argument, and you should see the text you send in your guest OS on the terminal in which you started qemu). With bochs, you can also use the "e9 hack" (when you enable that, then you can write characters to the bochs' terminal simply by using "out al, 0xe9").

This is what I use:
Code:
    unsigned char chrtoprint = 'A';
    asm volatile(
        "xorl %%ebx, %%ebx; movb %0, %%bl;"
#ifdef BOCHS
        // bochs e9 port hack
        "movb %%bl, %%al;outb %%al, $0xe9;"
#endif
        // print character on serial
        "movl $10000,%%ecx;movw $0x3fd,%%dx;"
        // transmit buffer ready?
        "1:inb %%dx, %%al;"
        "cmpb $0xff,%%al;je 2f;"
        "dec %%ecx;jz 2f;"
        "andb $0x20,%%al;jz 1b;"
        // send out character
        "subb $5,%%dl;movb %%bl, %%al;outb %%al, %%dx;2:"
    ::"r"(chrtoprint));
NOTE: On UEFI, the serial console is NOT initialized by default, you have to go to your UEFI manager's configuration and enable console (ConIn/ConOut) on serial feature manually. After that it will work in your kernel too. (You could also initialize the serial yourself, inline assembly example).

gerarparra0 wrote:
I've been testing it by adding code by parts to see what is not working but seems like the framebuffer is not responding.
Which version are you using? And which boot mechanism (RPi/x86 BIOS/x86 UEFI/Multiboot/El Torito...etc.)? Did it work before you added your code parts?

gerarparra0 wrote:
Excuse my poor makefile skillz, I'm pretty new at this :oops:
In the images folder you can find an example makefile to generate bootable disk images (along with a very simple mkimg.c image creator tool). First you should test your vm configuration with the sample disk images I provided.

I suggest to follow these steps to narrow down where the problem might be located:
1. run a provided image in your vm - this will test your execution environment. If this isn't okay, then check your vm's configuration.
2. try to create an image of your own with the example mykernel - this will test your build environment.
3. replace the example kernel and makefile with your own - if the error happens when you do so, then the problem is with your source.

Go to each step only when the previous steps are ok. If you can tell me at which step your problem appears, I'll be able to help more.

Cheers,
bzt


This is what I see when I run qemu with grub
Booting OS...
* Detecting CPU
* Enabling A20
* E820 Memory Map
* System tables
* System time
* Environment
* Autodetecting kernel
* Parsing ELF64
* Screen VESA VBE

This is with uefi
Booting OS...
* Locate initrd in Option ROMs
* Locate initrd in \BOOTBOOT\INITRD
* Gzip compressed initrd @2675000 551 bytes
* Initrd loaded @2672000 9728 bytes
* Environment @2675000 32 bytes
* Screen 800 x 600, scanline 3200, fb @80000000 1921024 bytes, type 1 ARGB
* System tables
* System time 2020-05-04 16:48:51 GMT+0:00
* cpio sys/core
* Autodetecting kernel

Then it just halts.. I tried debugging with gdb and breaking in the _start function and I see that the VM gets there and does the loops but nothing happens on the screen (After using info registers I suspected that the bootloader was pagefaulting because one of the registers said PF but I doubt thats what it means). Also I tried with the font and without to no avail. I am compiling for x86_64, I am using qemu as my emulator for x86_64, I tried using grub as bootloader as well as UEFI (tianoCore) and I am using the raw image files you have on your repo.
I might have messed something up by not copying your entire scripts, but where is the fun in that haha I guess I do have to take it slower. As soon as I get some free time I'll post my results with your steps. Thanks for responding @bzt!


Top
 Profile  
 
 Post subject: Re: BOOTBOOT kernel example not working
PostPosted: Thu May 07, 2020 3:25 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
gerarparra0 wrote:
I tried debugging with gdb and breaking in the _start function and I see that the VM gets there
You mean your kernel's _start function gets called? Then BOOTBOOT is working fine, there must be a linker script issue (misconfigured lfb address or something). Just to be on the safe side, in a debugger (bochs or qemu monitor) check if the framebuffer is mapped correctly ("page" in bochs, and if my memory serves "info mem" or "info page" in qemu). Note that the example linker script places the fb label at the framebuffer, so you can get the actual address with "&fb".

The files in the repo are tested and work on VirtualBox (BIOS, UEFI), qemu (BIOS, UEFI, RPi), bochs (BIOS) and on real hardware. If you have problems booting those, then there must be an issue with your VM configuration. Please show us your configuration (VB xml, qemu command line, bochsrc) maybe we can spot the problem.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: BOOTBOOT kernel example not working
PostPosted: Sun May 10, 2020 10:46 am 
Offline

Joined: Tue Apr 28, 2020 11:54 am
Posts: 3
Ok, so I think i found the problem.
The issue I was having was from mounting the bootpart.bin partition to a local directory with the wrong permissions. This came from your makefile:
"@sudo /usr/bin/mount -o loop,user bootpart.bin boot" line 35 on bootboot/images/Makefile
After some research i found out that mounting a FAT partition requires a uid and gid to be properly accessed so i modified it to the following
sudo bootpart.bin boot -o rw,uid=1000,gid=1000
this way, I do not need superuser permissions to mkdir or cp into the mounted boot/ partition.
like that your makefile runs flawlessly and I'm able to see the "Welcome from BOOTBOOT kernel..." and the colored squares! :D
I am not sure if I am completely missing the point here but your makefile also has this (which does not work on my system btw)
"@sudo /usr/bin/umount -f /dev/loop*" at line 47
wouldn't just "sudo umount -f boot" be able to unmount the filesystem?

Also, I part of the problem I was having is that I was using mkboot instead of mkimg by mistake :shock: OOPS!

Thank you so much for making me look into my Makefile and figuring out my problems! I am so excited to begin making my own kernel, thanks to your utilities.
Now I need to figure out how to implement paging, and interrupts on a 64-bit kernel but I have no clue where to start haha wish me luck!
Again thank you for yor work @bzt!


Top
 Profile  
 
 Post subject: Re: BOOTBOOT kernel example not working
PostPosted: Mon May 11, 2020 1:34 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
gerarparra0 wrote:
Ok, so I think i found the problem.
The issue I was having was from mounting the bootpart.bin partition to a local directory with the wrong permissions. This came from your makefile:
"@sudo /usr/bin/mount -o loop,user bootpart.bin boot" line 35 on bootboot/images/Makefile
After some research i found out that mounting a FAT partition requires a uid and gid to be properly accessed so i modified it to the following
sudo bootpart.bin boot -o rw,uid=1000,gid=1000
this way, I do not need superuser permissions to mkdir or cp into the mounted boot/ partition.
Thanks for the feedback! I've configured that in fstab and completely forgotten about it. Uid and gid should be added to the argument, thanks!

gerarparra0 wrote:
like that your makefile runs flawlessly and I'm able to see the "Welcome from BOOTBOOT kernel..." and the colored squares! :D
Well done! :-)

gerarparra0 wrote:
I am not sure if I am completely missing the point here but your makefile also has this (which does not work on my system btw)
"@sudo /usr/bin/umount -f /dev/loop*" at line 47
wouldn't just "sudo umount -f boot" be able to unmount the filesystem?
It is the same. Umounting with the device has the advantage that it umounts from multiple mount points should there be more. This step is important to flush the kernel cache so that the data actually gets written into the file. If the image file is still mounted somewhere else (unlikely, but could be), some data might be held back in the kernel cache.

gerarparra0 wrote:
Also, I part of the problem I was having is that I was using mkboot instead of mkimg by mistake :shock: OOPS!
Yes, mkboot is just a small tool to update the boot sector in an existing image (or on real disk device). On the other hand mkimg creates the entire image file, of which installing the boot sector is just one step.

gerarparra0 wrote:
Thank you so much for making me look into my Makefile and figuring out my problems! I am so excited to begin making my own kernel, thanks to your utilities.
Now I need to figure out how to implement paging, and interrupts on a 64-bit kernel but I have no clue where to start haha wish me luck!
Again thank you for yor work @bzt!
You are welcome! Thank you for your feedback! Start by reading our wiki, it is a great place to find information!

Cheers,
bzt


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

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