Multiboot2 bootloader not passing the elf sections tag

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.
Post Reply
forgetme11
Posts: 7
Joined: Mon Dec 09, 2024 12:29 am

Multiboot2 bootloader not passing the elf sections tag

Post by forgetme11 »

making me unable to remap the kernel's code and data in the new pagetable.
I found this "SORT_BY_NAME" modifier for ld

Code: Select all

        .text BLOCK(4K) : ALIGN(4K)
        {
                SORT_BY_NAME*(.00000multiboot)
                SORT_BY_NAME*(.text)
                SORT_BY_NAME*(.ZZZZZTEXT_END_ADDRESS)   # Needed because GRUB does not pass the elf headers tag.
        }
but it does not behave as expected (cant even load the multiboot header, though in ld's sections map (-M option) it shows up as the first section in .text, ZZZZZ... is confirmed to not work though)

Ideas?
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Multiboot2 bootloader not passing the elf sections tag

Post by MichaelPetch »

I'm not sure I understand the problem or what this solution you show is trying to fix. Part of me feels like this is an XY problem. Do you have a repository of your code online somewhere where we can see your project, code make files/build scripts etc so we can try to reproduce what the problem is?
forgetme11
Posts: 7
Joined: Mon Dec 09, 2024 12:29 am

Re: Multiboot2 bootloader not passing the elf sections tag

Post by forgetme11 »

This is the function where I am having trouble, grub only ever gives me one tag (no clue which one it is since gdb cant access the memory in the virtual machine) but it is not the efi symbols one (which is needed for me to remap the kernel's code and data in the new pagetable), apic_INIT_sipi() (supposedly) is what causes a bootloop (intended behaviour) on -enable-kvm but doesn't work in the emulator (made a thread about that)

Code: Select all

static void kernel_configure_memory(generic_memory_map_t* absmap, mb_elf_symbols_t* mb_section_headers){
	mb_elf_section_info_t ported_sections[5] = {0};
	char* section_names[] = {".text",".rodata",".bss",".data"};
	void* physical_memory_management_array = NULL;

	reposition_memory_map(absmap);

	_memory_manager_.amount = get_memory_size(absmap);
	physical_memory_management_array = boot_alloc(absmap,_memory_manager_.amount/8);

	if (elf_symbols == 0){
		outb(0x80,BOOTERR_BOOTLOADER_LEFT_UNBOOTABLE);
		apic_INIT_sipi();
	}else{
		elf_get_section_info_by_name(section_names[0],&ported_sections[0],(mb_elf_section_header_table_header_t*)mb_section_headers);
		elf_get_section_info_by_name(section_names[1],&ported_sections[1],(mb_elf_section_header_table_header_t*)mb_section_headers);
		elf_get_section_info_by_name(section_names[2],&ported_sections[2],(mb_elf_section_header_table_header_t*)mb_section_headers);
		elf_get_section_info_by_name(section_names[3],&ported_sections[3],(mb_elf_section_header_table_header_t*)mb_section_headers);
	}

	ported_sections[4].physaddr = physical_memory_management_array;
	ported_sections[4].size = _memory_manager_.amount/8;

	fill_memory_manager(absmap);

	x64_desc_table_pointer_t desctab_whore_pointer = {0};
	desctab_whore_pointer.address = &bsp_tmp_gdt;

	lgdt(&desctab_whore_pointer);
	desctab_whore_pointer.address = &interrupt_descriptor_table;
	lidt(&desctab_whore_pointer);

	if (_memory_manager_.amount > (1<<(4*9))/2){
		_mmu_.pagetree_levels = 5;
	}else{	_mmu_.pagetree_levels = 4;}

	pagetable_t* ghosttree = boot_alloc(absmap,4096);

	boot_identity_map(ghosttree,ported_sections[0].physaddr,ported_sections[0].size,DEFAULT_CACHE);
	boot_identity_map(ghosttree,ported_sections[1].physaddr,ported_sections[1].size,DEFAULT_CACHE);
	boot_identity_map(ghosttree,ported_sections[2].physaddr,ported_sections[2].size,DEFAULT_CACHE);
	boot_identity_map(ghosttree,ported_sections[3].physaddr,ported_sections[3].size,DEFAULT_CACHE);
	boot_identity_map(ghosttree,ported_sections[4].physaddr,ported_sections[4].size,DEFAULT_CACHE);
	boot_identity_map(ghosttree,get_local_apic(),4096,CACHE_MMIO);

	__asm__ volatile(
	".p2align 6		\n\t"	/* Telling the assembler to align the code to 2^6 bytes */
	"mov	%%cr3,%%rax	\n\t"
	"or	%0,%%rax	\n\t"
	"mov	%%rax,%%cr3	\n\t"	/* Not serializing until cr4 has been dealt with */
	"mov	%%cr4,%%rax	\n\t"	/* Setting the pagetree to 4 levels */
	"and	%1,%%rax	\n\t"
	"mov	%%rax,%%cr4	\n\t"
	"jmp	0		\n\t"
	::"r"((uint64_t)ghosttree),"r"(UINT64_MAX^(_mmu_.pagetree_levels==4?1<<12:0)):"%rax");

	_KERNELSPACE_.address_space.pagetree = ghosttree;

	_memory_manager_.pointer = physical_memory_management_array;
}
Though I don't really care anymore, I am going to make a small bootloader in a windows iso, I don't want to hear "multiboot" ever again in my life, we are like monkeys to grub developers, the spelling errors in the "Standard" should have been enough of a warning, alas here we are.

I don't have a repository on the web

edit: talk about spelling mistakes
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Multiboot2 bootloader not passing the elf sections tag

Post by Octocontrabass »

forgetme11 wrote: Tue Dec 10, 2024 10:47 pm(no clue which one it is since gdb cant access the memory in the virtual machine)
How are you attaching GDB to your virtual machine?
forgetme11 wrote: Tue Dec 10, 2024 10:47 pm

Code: Select all

	"mov	%%cr4,%%rax	\n\t"	/* Setting the pagetree to 4 levels */
You can't switch between 4-level and 5-level paging while paging is enabled.
forgetme11 wrote: Tue Dec 10, 2024 10:47 pmI am going to make a small bootloader in a windows iso
Maybe Limine is closer to what you want? It'll save you the trouble of writing a bootloader.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Multiboot2 bootloader not passing the elf sections tag

Post by iansjack »

Are you sure that you are not making the same mistake that you did with the magic number when interpreting multi-byte values?

I don’t understand what your problem with gdb is - it would be pretty useless if it couldn’t access virtual addresses. But, if you use qemu it has a built-in monitor which can provide a load of information. Use it to inspect a range of memory as bytes, words, integers, and longs to be sure that you understand how memory layout works.

Multiboot really isn’t as difficult as you think. If it was it would never have become so popular.

A public repository is highly recommended if you want to ask others for help. People invariably post the wrong section of code when asking for help with errors.
Post Reply