Check if cross compiler broken? 40kb .img file

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
Paletech35
Posts: 8
Joined: Sun Mar 28, 2021 6:30 pm

Check if cross compiler broken? 40kb .img file

Post by Paletech35 »

I ve been trying to write an OS for raspberry pi, and I made a cross compiler exactly as described on the wiki with arm-none-eabi as the target. Everything has been working until now, when I am trying to implement interrupts. I noticed when I first compiled the rPi bare bones example it had a size of 40kb, which I though was too large, but It seemed to work. Now when I am trying to implement interrupts, I was not getting the expected result and have determined that my interrupts handler function in irq_handler.c is not running. Is it possible that I messed up my cross compiler, or are there any other issues that could cause this? I think possibly the exception vector table isnt truly being moved to the beginning of memory. Code is at github in case that helps, I am running it on a raspberry pi model 1. Thanks!
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Check if cross compiler broken? 40kb .img file

Post by Octocontrabass »

You're right, it's too large. There's a huge block of extra padding that causes your kernel to be loaded at the wrong address, so your exception vectors don't point to your kernel.

I notice the wiki uses "-fpic", but this should be completely unnecessary as long as the kernel is loaded at the correct address. Did the author of that article have the same issue and simply not notice?

Remove "-fpic" from all commands in your makefile. Add "-Wl,-z,max-page-size=0x1000" to your link command.
Paletech35
Posts: 8
Joined: Sun Mar 28, 2021 6:30 pm

Re: Check if cross compiler broken? 40kb .img file

Post by Paletech35 »

Thanks, I have removed all -fpic options and added the -Wl options, but the .img file is only a couple hundred bytes smaller now, and interrupts still aren't working. Is there anything else that could be causing this? Having looked at the sizes of all the files, I noticed that boot.S compiled into 33696 bytes as boot.o, and all other files are a reasonable size. I imagine this is what's causing the issues. The contents of boot.S are exactly as on the wiki.
EDIT: I noticed that the linker was putting boot.o at 0x8000 which then contained 0x8000 of padding. I removed the padding, and boot.o is still almost 1kb, bigger than boot.S, which still seems off to me, and interrupts still dont work :(. The .img file is only 14kb now tho :)
Paletech35
Posts: 8
Joined: Sun Mar 28, 2021 6:30 pm

Re: Check if cross compiler broken? 40kb .img file

Post by Paletech35 »

Would it be possible to create a new section in the linker, and make my exception vector table in a .S file that gets put in the new section? Then I just place the new section at 0x0000 before the rest of the kernel is loaded at 0x8000? Something like:
linker.ld:

Code: Select all

ENTRY(_start)
SECTIONS
{
    .vectable:
    {
        *(.vectable)
    }

    . = 0x8000;
    __start = .;
    __text_start = .;
    .text :
    {
        KEEP(*(.text.boot))
        *(.text)
    }
    . = ALIGN(4096); /* align to page size */
    __text_end = .;

    ...
    
    __end = .;

}
exception_vector.S:

Code: Select all

.section "vectable"
	ldr	pc, res_abs_addr
	ldr	pc, undef_abs_addr
	ldr	pc, swi_abs_addr
	ldr	pc, prefetch_abort_abs_addr
	ldr	pc, data_abort_abs_addr
	nop
	ldr	pc, irq_abs_addr
	ldr	pc, fiq_abs_addr

res_abs_addr:			.word reset_handler
undef_abs_addr:			.word undefined_instruction_handler
swi_abs_addr:			.word swi_handler
prefetch_abort_abs_addr:	.word prefetch_abort_handler
data_abort_abs_addr:		.word data_abort_handler
irq_abs_addr:			.word irq_handler_wrapper
fiq_abs_addr:			.word fiq_handler
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Check if cross compiler broken? 40kb .img file

Post by Octocontrabass »

Paletech35 wrote:I removed the padding, and boot.o is still almost 1kb, bigger than boot.S, which still seems off to me, and interrupts still dont work :(. The .img file is only 14kb now tho :)
Hmm, that should fix the problem. I'll have to take another look.
Paletech35 wrote:Would it be possible to create a new section in the linker, and make my exception vector table in a .S file that gets put in the new section? Then I just place the new section at 0x0000 before the rest of the kernel is loaded at 0x8000?
No. If you do that, the new section will be loaded at 0x8000, and your kernel won't work.
Paletech35
Posts: 8
Joined: Sun Mar 28, 2021 6:30 pm

Re: Check if cross compiler broken? 40kb .img file

Post by Paletech35 »

Octocontrabass wrote:
Paletech35 wrote:Would it be possible to create a new section in the linker, and make my exception vector table in a .S file that gets put in the new section? Then I just place the new section at 0x0000 before the rest of the kernel is loaded at 0x8000?
No. If you do that, the new section will be loaded at 0x8000, and your kernel won't work.
Isnt that what the linker is for? I would just add the new section BEFORE using . = 0x8000; in the linker, so the new section is loaded at 0x0000 then .text.data is loaded at 0x8000 as per usual since it is after the . = 0x8000; command in linker.ld. Something like:

Code: Select all

. = 0x0000;
//add .vectable section
. = 0x8000;
//add the rest of the sections
I tried it and the kernel still boots up, although interrupts still dont work :(
Paletech35
Posts: 8
Joined: Sun Mar 28, 2021 6:30 pm

Re: Check if cross compiler broken? 40kb .img file

Post by Paletech35 »

Out of curiosity, I compiled an empty .S file with my cross compiler and the .o file came to 548 bytes. I assume this is because its including references to libraries or something. Either way, it seems too big to me, and I think it could be because my I compiled my cross compiler incorrectly, as it shouldnt contain any references to any libraries since it is a cross compiler and I havent linked to any of my own code. Is there anyway to test if it is broken/ compiling for userspace code? The only other error I can currently see is if my exception vector table isnt really being moved to the beginning of memory. Are there any easy ways I can check this? Thanks
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Check if cross compiler broken? 40kb .img file

Post by Octocontrabass »

Paletech35 wrote:Isnt that what the linker is for? I would just add the new section BEFORE using . = 0x8000; in the linker, so the new section is loaded at 0x0000 then .text.data is loaded at 0x8000 as per usual since it is after the . = 0x8000; command in linker.ld.
No. The linker does not control where the kernel binary will be loaded. The kernel binary will always be loaded at 0x8000.
Paletech35 wrote:Out of curiosity, I compiled an empty .S file with my cross compiler and the .o file came to 548 bytes.
That sounds normal to me.
Paletech35 wrote:The only other error I can currently see is if my exception vector table isnt really being moved to the beginning of memory. Are there any easy ways I can check this?
Run it in QEMU and use a debugger. Although, you haven't actually described what's not working - are you sure interrupts are happening at all? Maybe see if SWI calls the handler before trying hardware interrupts.
Post Reply