C code rebooting for no reason

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

C code rebooting for no reason

Post by NunoLava1998 »

I've finally did the Bare Bones tutorial and it's almost time to move into the Meaty Skeleton. How great. And without GRUB, i just wrote a simple assembler bootloader, as GRUB4DOS/Syslinux had problems on my PC.
I can boot it in real hardware, which is pretty good. But it reboots the PC. My BIOS menu is written in C, and rebooting from there normally gives a few frames of VESA/VGA garbage, then reboots properly. The same happens on the fulldisk.img i have created, suggesting the C code is rebooting for some reason. The assembly bootloader loads Protected mode and loads the GDTR, and then at the very end switches to 32 bit right before the jump to 0x07E00 instruction, which should make it protected mode 32 bit and NASM compiled it correctly. I do 0x13 before moving to 32bit protected mode, THEN jump to protected mode and go to 32bit code, then jump to the myos.bin/boot.asm. The A20 line is not enabled.
Here is the code:

Code: Select all

/* Surely you will remove the processor conditionals and this comment
   appropriately depending on whether or not you use C++. */
#if !defined(__cplusplus)
#include <stdbool.h> /* C doesn't have booleans by default. */
#endif
#include <stddef.h>
#include <stdint.h>
 
/* Check if the compiler thinks we are targeting the wrong operating system. */
#if defined(__linux__)
#error "You are not using a cross-compiler, you will most certainly run into trouble"
#endif
 
/* This tutorial will only work for the 32-bit ix86 targets. */
#if !defined(__i386__)
#error "This tutorial needs to be compiled with a ix86-elf compiler"
#endif
 
/* Hardware text mode color constants. */
enum vga_color {
	VGA_COLOR_BLACK = 0,
	VGA_COLOR_BLUE = 1,
	VGA_COLOR_GREEN = 2,
	VGA_COLOR_CYAN = 3,
	VGA_COLOR_RED = 4,
	VGA_COLOR_MAGENTA = 5,
	VGA_COLOR_BROWN = 6,
	VGA_COLOR_LIGHT_GREY = 7,
	VGA_COLOR_DARK_GREY = 8,
	VGA_COLOR_LIGHT_BLUE = 9,
	VGA_COLOR_LIGHT_GREEN = 10,
	VGA_COLOR_LIGHT_CYAN = 11,
	VGA_COLOR_LIGHT_RED = 12,
	VGA_COLOR_LIGHT_MAGENTA = 13,
	VGA_COLOR_LIGHT_BROWN = 14,
	VGA_COLOR_WHITE = 15,
};
 
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) {
	return fg | bg << 4;
}
 
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
	return (uint16_t) uc | (uint16_t) color << 8;
}
 
size_t strlen(const char* str) {
	size_t len = 0;
	while (str[len])
		len++;
	return len;
}
 
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
 
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
 
void terminal_initialize(void) {
	terminal_row = 0;
	terminal_column = 0;
	terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
	terminal_buffer = (uint16_t*) 0xB8000;
	for (size_t y = 0; y < VGA_HEIGHT; y++) {
		for (size_t x = 0; x < VGA_WIDTH; x++) {
			const size_t index = y * VGA_WIDTH + x;
			terminal_buffer[index] = vga_entry(' ', terminal_color);
		}
	}
}
 
void terminal_setcolor(uint8_t color) {
	terminal_color = color;
}
 
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) {
	const size_t index = y * VGA_WIDTH + x;
	terminal_buffer[index] = vga_entry(c, color);
}
 
void terminal_putchar(char c) {
	terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
	if (++terminal_column == VGA_WIDTH) {
		terminal_column = 0;
		if (++terminal_row == VGA_HEIGHT)
			terminal_row = 0;
	}
}
 
void terminal_write(const char* data, size_t size) {
	for (size_t i = 0; i < size; i++)
		terminal_putchar(data[i]);
}
 
void terminal_writestring(const char* data) {
	terminal_write(data, strlen(data));
}
 
#if defined(__cplusplus)
extern "C" /* Use C linkage for kernel_main. */
#endif
void kernel_main(void) {
	/* Initialize terminal interface */
	terminal_initialize();
 
	/* Newline support is left as an exercise. */
	terminal_writestring("C");
}
exactly the same as the suggested kernel.c in the bare bones tutorial, but instead of "Hello, Kernel World!\n" it's "C", without any newlines, so this should work, and it compiled fine.

Why is my hardware rebooting?
If you're even asking for the motherboard:
H81 model, GIGABYTE vendor, UEFI.
I don't have an option to boot from UEFI on the USB.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: C code rebooting for no reason

Post by glauxosdever »

Hi,


Your bootloader is probably faulty. Do you even load your kernel from your bootloader?

However, as I said in another thread, my recommendation is to write your own bootloader and boot specification only after you have gained some more experience and have seen in what ways current bootloaders and boot specifications are suboptimal. For now, you should use GRUB in order to know more about it and not to repeat its design mistakes.


Regards,
glauxosdever
Last edited by glauxosdever on Sun Oct 23, 2016 12:30 pm, edited 2 times in total.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: C code rebooting for no reason

Post by Roman »

What do you think myos.bin contains?
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: C code rebooting for no reason

Post by NunoLava1998 »

Roman wrote:What do you think myos.bin contains?
I looked at it on the hex editor and i see ELF code, and it compiled successfully. Likely not corrupt.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: C code rebooting for no reason

Post by NunoLava1998 »

glauxosdever wrote:Hi,


Your bootloader is probably faulty. Do you even load your kernel from your bootloader?

However, as I said in another thread, my recommendation is to write your own bootloader and boot specification only after you have gained some more experience and have seen in what ways current bootloaders and boot specifications are suboptimal. For now, you should use GRUB in order to know more about it and not to repeat its design mistakes.


Regards,
glauxosdever
Yes. My bootloader changes to protected mode, 32 bit after a 0x13 disk read into memory which doesn't really read the code. After that, it jumps to 0x7e00:0x0000, aka the second sector. I cannot use GRUB since my system literally goes "i'm done, go to main HDD" with GRUB.
I do load my kernel, and my img file which i writed using Win32 Disk Imager into my USB has the bootloader at 0x7C00 (aka the literal first sector, in a hex editor it's the first sector indeed), and at 0x7E00, there is the ELF code. It starts at 200 in hex, aka 513 in decimal.

TL;DR yes, did what GRUB usually does.
It is probably not faulty since the reboot garbage only occurs when you're in higher-lower level languages (or just C), and not Assembly, which my bootloader is written in. A assembly reboot does not display the "garbage".
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
User avatar
Ch4ozz
Member
Member
Posts: 170
Joined: Mon Jul 18, 2016 2:46 pm
Libera.chat IRC: esi

Re: C code rebooting for no reason

Post by Ch4ozz »

Get a VM and test your stuff there before throwing garbage at your real hardware.
Getting GRUB to work on a real machine should be a matter of seconds by changing the boot order to USB first, works perfectly fine on all of my machines at home.
Also GRUB is a way more powerful then your bootloader, you should only write a bootloader if you really need it in case of security or flexibility.
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: C code rebooting for no reason

Post by glauxosdever »

Hi,


Please answer these questions first so we know that you know what are you doing.
  • Do you load the kernel from a filesystem, or is it hardcoded to be in some sector, or...?
  • Do you parse the ELF binary format?
  • Did you change your linker script to make the entry point at 0x00007E00?
  • Are you sure 0x200 == 513?
  • Is being unable to get GRUB to work really a reason to write your own bootloader?
Otherwise you have just proven you are not ready for OS development.


Regards,
glauxosdever
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: C code rebooting for no reason

Post by NunoLava1998 »

glauxosdever wrote:Hi,


Please answer these questions first so we know that you know what are you doing.
  • Do you load the kernel from a filesystem, or is it hardcoded to be in some sector, or...?
  • Do you parse the ELF binary format?
  • Did you change your linker script to make the entry point at 0x00007E00?
  • Are you sure 0x200 == 513?
  • Is being unable to get GRUB to work really a reason to write your own bootloader?
Otherwise you have just proven you are not ready for OS development.


Regards,
glauxosdever
1: Hardcoded at sector 2 and can be expanded to the other sectors.
2: If you mean "enabling 32BIT and enabling the PE byte", yes. If you mean if i compiled it correctly, obviously yes lmao, and if you mean something else, no.
3: No, but the myos.bin is located at 0x7E00, meaning it probably isn't needed. I used dd.
4: Assuming byte 0 doesn't exist, yes. If byte 0 does exist, no, and 0x200 = 512. Normally, 0x200 would be 512, as most devices have a byte 0.
5: I can't use GRUB, it's not possible, especially in Windows. So i decided to write my bootloader, as that was the first idea that came to mind. And it worked. I mean, if it restarts in C mode, it likely worked (and the linker worked).
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: C code rebooting for no reason

Post by NunoLava1998 »

Ch4ozz wrote:Get a VM and test your stuff there before throwing garbage at your real hardware.
Getting GRUB to work on a real machine should be a matter of seconds by changing the boot order to USB first, works perfectly fine on all of my machines at home.
Also GRUB is a way more powerful then your bootloader, you should only write a bootloader if you really need it in case of security or flexibility.
I use the boot menu, and i have already tried to change it to the first option. Still doesn't work.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: C code rebooting for no reason

Post by glauxosdever »

Hi,

NunoLava1998 wrote:
glauxosdever wrote:Do you load the kernel from a filesystem, or is it hardcoded to be in some sector, or...?
Hardcoded at sector 2 and can be expanded to the other sectors.
Good to know that you know how is the layout on the disk. You passed this question.
NunoLava1998 wrote:
glauxosdever wrote:Do you parse the ELF binary format?
If you mean "enabling 32BIT and enabling the PE byte", yes. If you mean if i compiled it correctly, obviously yes lmao, and if you mean something else, no.
I meant parsing the ELF format, that is extract different information from it and load each section to the appropriate address. Giving you another chance on this question.
NunoLava1998 wrote:
glauxosdever wrote:Did you change your linker script to make the entry point at 0x00007E00?
No, but the myos.bin is located at 0x7E00, meaning it probably isn't needed. I used dd.
You load it there, but jumps in your code have references as if it was loaded at 0x00100000. You failed on this question.
NunoLava1998 wrote:
glauxosdever wrote:Are you sure 0x200 == 513?
Assuming byte 0 doesn't exist, yes. If byte 0 does exist, no, and 0x200 = 512. Normally, 0x200 would be 512, as most devices have a byte 0.
It hasn't to do with indexing. 0x200 == 512, always. You failed on this question too.
NunoLava1998 wrote:
glauxosdever wrote:Is being unable to get GRUB to work really a reason to write your own bootloader?
I can't use GRUB, it's not possible, especially in Windows. So i decided to write my bootloader, as that was the first idea that came to mind. And it worked. I mean, if it restarts in C mode, it likely worked (and the linker worked).
It will take more time to get a working bootloader than to get GRUB to work. And no, your bootloader didn't work. You failed on yet another question.


I apologise for all of this bittering, but I think you need to realise you lack a lot of knowledge needed to write a bootloader and/or an operating system.


Regards,
glauxosdever
NunoLava1998
Member
Member
Posts: 273
Joined: Sun Oct 09, 2016 4:38 am
Libera.chat IRC: NunoLava1998

Re: C code rebooting for no reason

Post by NunoLava1998 »

glauxosdever wrote:Hi,

NunoLava1998 wrote:
glauxosdever wrote:Do you load the kernel from a filesystem, or is it hardcoded to be in some sector, or...?
Hardcoded at sector 2 and can be expanded to the other sectors.
Good to know that you know how is the layout on the disk. You passed this question.
NunoLava1998 wrote:
glauxosdever wrote:Do you parse the ELF binary format?
If you mean "enabling 32BIT and enabling the PE byte", yes. If you mean if i compiled it correctly, obviously yes lmao, and if you mean something else, no.
I meant parsing the ELF format, that is extract different information from it and load each section to the appropriate address. Giving you another chance on this question.
NunoLava1998 wrote:
glauxosdever wrote:Did you change your linker script to make the entry point at 0x00007E00?
No, but the myos.bin is located at 0x7E00, meaning it probably isn't needed. I used dd.
You load it there, but jumps in your code have references as if it was loaded at 0x00100000. You failed on this question.
NunoLava1998 wrote:
glauxosdever wrote:Are you sure 0x200 == 513?
Assuming byte 0 doesn't exist, yes. If byte 0 does exist, no, and 0x200 = 512. Normally, 0x200 would be 512, as most devices have a byte 0.
It hasn't to do with indexing. 0x200 == 512, always. You failed on this question too.
NunoLava1998 wrote:
glauxosdever wrote:Is being unable to get GRUB to work really a reason to write your own bootloader?
I can't use GRUB, it's not possible, especially in Windows. So i decided to write my bootloader, as that was the first idea that came to mind. And it worked. I mean, if it restarts in C mode, it likely worked (and the linker worked).
It will take more time to get a working bootloader than to get GRUB to work. And no, your bootloader didn't work. You failed on yet another question.


I apologise for all of this bittering, but I think you need to realise you lack a lot of knowledge needed to write a bootloader and/or an operating system.


Regards,
glauxosdever
2: Probably not, maybe i will go assembly all the way and build a C interpreter later.
3: Except you do not need to do "ORG 0x0100" or something (that won't work). You need to do "ORG 0x0", which fortunately by default compilers do include, so it's a "yes", most likely.
4: I do know 0x200 is 512. And it is, you're correct, i was half correct.
5: Hey, the bootloader does work most likely.
Developing TRIODIUM OS. Or call it Dixium if you want. It doesn't matter.

https://github.com/NunoLava1998/DixiumOS
glauxosdever
Member
Member
Posts: 501
Joined: Wed Jun 17, 2015 9:40 am
Libera.chat IRC: glauxosdever
Location: Athens, Greece

Re: C code rebooting for no reason

Post by glauxosdever »

Hi,

NunoLava1998 wrote:Probably not, maybe i will go assembly all the way and build a C interpreter later.
So you will use assembly just because you can't parse ELF (and you wouldn't need to do it if you used GRUB)? You can still request your toolchain to convert the ELF to a flat binary.
NunoLava1998 wrote:Except you do not need to do "ORG 0x0100" or something (that won't work). You need to do "ORG 0x0", which fortunately by default compilers do include, so it's a "yes", most likely.
And I was talking about the kernel code, which is linked to 0x00100000 according to the linker script, and not 0x00007E00 where you are loading it.
NunoLava1998 wrote:I do know 0x200 is 512. And it is, you're correct, i was half correct.
No, you were plain wrong. 0 can't not exist.
NunoLava1998 wrote:Hey, the bootloader does work most likely.
Can it successfully pass control to the kernel? No, therefore it does not work.


Regards,
glauxosdever
FusT
Member
Member
Posts: 91
Joined: Wed Sep 19, 2012 3:43 am
Location: The Netherlands

Re: C code rebooting for no reason

Post by FusT »

I'm with glauxosdever on this.

I really think you should put more effort in getting GRUB to work on your system, perhaps using a linux VM. Writing a (good) bootloader is like writing an operating system of it's own.
Also, get yourself an emulator/simulator with good debugging capabilities (like BOCHS) and actually check where your code reboots the machine/outputs garbage.

I'm not trying to sound condescending but I too really think you are missing some basic skills/knowledge to be able to write an operating system. The motivation is there but your current approach (shotgun debugging/copy-pasting from SO) is not going to get you anywhere fast.

Just my 2 cents

EDIT:
Thought i'd also be constructive on the problem.
I'm 99% sure it's not the C code that causes the reboot, but an error in your custom bootloader (e.g. one of the things glauxosdever pointed out on relocation and ELF parsing).
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: C code rebooting for no reason

Post by iansjack »

Contrary to your subject heading, there is a reason why your code is rebooting. Accept that simple fact and you are on the way to solvng your problem.

A virtual machine and a debugger (Bochs or qemu + gdb) will be a great aid in helping you determine where the fault lies. Finding it may even teach you something.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: C code rebooting for no reason

Post by Roman »

I looked at it on the hex editor and i see ELF code, and it compiled successfully. Likely not corrupt.
So do you think an ELF file can be simply executed with JMP?

BTW, writing a C interpreter is comparable in complexity to writing an OS.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
Post Reply