Page 2 of 3

Re: Raspberry PI Bare Bones OS

Posted: Sun May 30, 2021 7:09 pm
by ssjcoder
if gcc is so messy, byzantine and just f&cked up with this respect, maybe try clang as already suggested? for example, I got it on my Windows machine, messed around a bit with its (pretty sucky, admittedly) documentation and after a short time - was able to compile an aarch64 PE image of my UEFI OS Loader for ARM boards. and it worked just like the MSVC build. these two look like being crosscompilers by design and they let you compile/link even freestanding things pretty easy. ethin gave you a useful link. it's incomplete unfortunately, because, well lines like "target maybe A, B, C, etc" is not what one expects from a reference. should I guess, what that "etc" hides? :D if you don't like the idea of having a dozen of gcc builds for everything, and want to do your work on RPi, then your answer is clang.
Thanks for the input, I looked a bit into it, if it becomes a better option and GCC doesn't work for me I might give it a shot.

---

So, after doing some tinkering around I decided to attempt using local (not cross-compiler) gcc, see if that works.

This is my boot.S file:

Code: Select all

// AArch32 mode
 
// To keep this in the first portion of the binary.
.section ".text.boot"
 
// Make _start global.
.globl _start
 
        .org 0x8000
// Entry point for the kernel.
// r15 -> should begin execution at 0x8000.
// r0 -> 0x00000000
// r1 -> 0x00000C42 - machine id
// r2 -> 0x00000100 - start of ATAGS
// preserve these registers as argument for kernel_main
_start:
	// Shut off extra cores
	mrc p15, 0, r5, c0, c0, 5
	and r5, r5, #3
	cmp r5, #0
	bne halt
 
	// Setup the stack.
	ldr r5, =_start
	mov sp, r5
 
	// Clear out bss.
	ldr r4, =__bss_start
	ldr r9, =__bss_end
	mov r5, #0
	mov r6, #0
	mov r7, #0
	mov r8, #0
	b       2f
 
1:
	// store multiple at r4.
	stmia r4!, {r5-r8}
 
	// If we are still below bss_end, loop.
2:
	cmp r4, r9
	blo 1b
 
	// Call kernel_main
	ldr r3, =kernel_main
	blx r3
 
	// halt
halt:
	wfe
	b halt
this is my kernel.c file:

Code: Select all

#include <stddef.h>
#include <stdint.h>
 
static uint32_t MMIO_BASE;
 
// The MMIO area base address, depends on board type
static inline void mmio_init(int raspi)
{
    switch (raspi) {
        case 2:
        case 3:  MMIO_BASE = 0x3F000000; break; // for raspi2 & 3
        case 4:  MMIO_BASE = 0xFE000000; break; // for raspi4
        default: MMIO_BASE = 0x20000000; break; // for raspi1, raspi zero etc.
    }
}
 
// Memory-Mapped I/O output
static inline void mmio_write(uint32_t reg, uint32_t data)
{
	*(volatile uint32_t*)(MMIO_BASE + reg) = data;
}
 
// Memory-Mapped I/O input
static inline uint32_t mmio_read(uint32_t reg)
{
	return *(volatile uint32_t*)(MMIO_BASE + reg);
}
 
// Loop <delay> times in a way that the compiler won't optimize away
static inline void delay(int32_t count)
{
	asm volatile("__delay_%=: subs %[count], %[count], #1; bne __delay_%=\n"
		 : "=r"(count): [count]"0"(count) : "cc");
}
 
enum
{
    // The offsets for reach register.
    GPIO_BASE = 0x200000,
 
    // Controls actuation of pull up/down to ALL GPIO pins.
    GPPUD = (GPIO_BASE + 0x94),
 
    // Controls actuation of pull up/down for specific GPIO pin.
    GPPUDCLK0 = (GPIO_BASE + 0x98),
 
    // The base address for UART.
    UART0_BASE = (GPIO_BASE + 0x1000), // for raspi4 0xFE201000, raspi2 & 3 0x3F201000, and 0x20201000 for raspi1
 
    // The offsets for reach register for the UART.
    UART0_DR     = (UART0_BASE + 0x00),
    UART0_RSRECR = (UART0_BASE + 0x04),
    UART0_FR     = (UART0_BASE + 0x18),
    UART0_ILPR   = (UART0_BASE + 0x20),
    UART0_IBRD   = (UART0_BASE + 0x24),
    UART0_FBRD   = (UART0_BASE + 0x28),
    UART0_LCRH   = (UART0_BASE + 0x2C),
    UART0_CR     = (UART0_BASE + 0x30),
    UART0_IFLS   = (UART0_BASE + 0x34),
    UART0_IMSC   = (UART0_BASE + 0x38),
    UART0_RIS    = (UART0_BASE + 0x3C),
    UART0_MIS    = (UART0_BASE + 0x40),
    UART0_ICR    = (UART0_BASE + 0x44),
    UART0_DMACR  = (UART0_BASE + 0x48),
    UART0_ITCR   = (UART0_BASE + 0x80),
    UART0_ITIP   = (UART0_BASE + 0x84),
    UART0_ITOP   = (UART0_BASE + 0x88),
    UART0_TDR    = (UART0_BASE + 0x8C),
 
    // The offsets for Mailbox registers
    MBOX_BASE    = 0xB880,
    MBOX_READ    = (MBOX_BASE + 0x00),
    MBOX_STATUS  = (MBOX_BASE + 0x18),
    MBOX_WRITE   = (MBOX_BASE + 0x20)
};
 
// A Mailbox message with set clock rate of PL011 to 3MHz tag
volatile unsigned int  __attribute__((aligned(16))) mbox[9] = {
    9*4, 0, 0x38002, 12, 8, 2, 3000000, 0 ,0
};
 
void uart_init(int raspi)
{
	mmio_init(raspi);
 
	// Disable UART0.
	mmio_write(UART0_CR, 0x00000000);
	// Setup the GPIO pin 14 && 15.
 
	// Disable pull up/down for all GPIO pins & delay for 150 cycles.
	mmio_write(GPPUD, 0x00000000);
	delay(150);
 
	// Disable pull up/down for pin 14,15 & delay for 150 cycles.
	mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15));
	delay(150);
 
	// Write 0 to GPPUDCLK0 to make it take effect.
	mmio_write(GPPUDCLK0, 0x00000000);
 
	// Clear pending interrupts.
	mmio_write(UART0_ICR, 0x7FF);
 
	// Set integer & fractional part of baud rate.
	// Divider = UART_CLOCK/(16 * Baud)
	// Fraction part register = (Fractional part * 64) + 0.5
	// Baud = 115200.
 
	// For Raspi3 and 4 the UART_CLOCK is system-clock dependent by default.
	// Set it to 3Mhz so that we can consistently set the baud rate
	if (raspi >= 3) {
		// UART_CLOCK = 30000000;
		unsigned int r = (((unsigned int)(&mbox) & ~0xF) | 8);
		// wait until we can talk to the VC
		while ( mmio_read(MBOX_STATUS) & 0x80000000 ) { }
		// send our message to property channel and wait for the response
		mmio_write(MBOX_WRITE, r);
		while ( (mmio_read(MBOX_STATUS) & 0x40000000) || mmio_read(MBOX_READ) != r ) { }
	}
 
	// Divider = 3000000 / (16 * 115200) = 1.627 = ~1.
	mmio_write(UART0_IBRD, 1);
	// Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
	mmio_write(UART0_FBRD, 40);
 
	// Enable FIFO & 8 bit data transmission (1 stop bit, no parity).
	mmio_write(UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6));
 
	// Mask all interrupts.
	mmio_write(UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6) |
	                       (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10));
 
	// Enable UART0, receive & transfer part of UART.
	mmio_write(UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
}
 
void uart_putc(unsigned char c)
{
	// Wait for UART to become ready to transmit.
	while ( mmio_read(UART0_FR) & (1 << 5) ) { }
	mmio_write(UART0_DR, c);
}
 
unsigned char uart_getc()
{
    // Wait for UART to have received something.
    while ( mmio_read(UART0_FR) & (1 << 4) ) { }
    return mmio_read(UART0_DR);
}
 
void uart_puts(const char* str)
{
	for (size_t i = 0; str[i] != '\0'; i ++)
		uart_putc((unsigned char)str[i]);
}
 
#if defined(__cplusplus)
extern "C" /* Use C linkage for kernel_main. */
#endif
 
#ifdef AARCH64
// arguments for AArch64
void kernel_main(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3)
#else
// arguments for AArch32
void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
#endif
{
	// initialize UART for Raspi2
	uart_init(3);
	uart_puts("Hello, kernel World!\r\n");
 
	while (1)
		uart_putc(uart_getc());
}

This is my linker.ld file:

Code: Select all

ENTRY(_start)
 
SECTIONS
{
    /* Starts at LOADER_ADDR. */
    . = 0x8000;
    /* For AArch64, use . = 0x80000; */
    __start = .;
    __text_start = .;
    .text :
    {
        KEEP(*(.text.boot))
        *(.text)
    }
    . = ALIGN(4096); /* align to page size */
    __text_end = .;
 
    __rodata_start = .;
    .rodata :
    {
        *(.rodata)
    }
    . = ALIGN(4096); /* align to page size */
    __rodata_end = .;
 
    __data_start = .;
    .data :
    {
        *(.data)
    }
    . = ALIGN(4096); /* align to page size */
    __data_end = .;
 
    __bss_start = .;
    .bss :
    {
        bss = .;
        *(.bss)
    }
    . = ALIGN(4096); /* align to page size */
    __bss_end = .;
    __bss_size = __bss_end - __bss_start;
    __end = .;
}
these are just copied from the raspberry pi bare bones tutorial, these are my bash commands:

Code: Select all

gcc -mcpu=cortex-a53 -fpic -ffreestanding -c boot.S -o boot.o
gcc -mcpu=cortex-a53 -fpic -ffreestanding -std=gnu99 -c kernel.c -o kernel.o -O2 -Wall -Wextra
gcc -T linker.ld -o myos.elf -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
objcopy myos.elf -O binary kernel7.img
this generates a file, "kernel7.img", 40.1 KB in size, however, when I replace my target SD card's "kernel7.img" it causes it to boot to the rainbow screen and just hang, not displaying any message or anything.

any idea what the problem could be?

Re: Raspberry PI Bare Bones OS

Posted: Sun May 30, 2021 8:28 pm
by Ethin
You used your local compiler and it wasn't built for cross-compilation. Therefore, it built it with the assumption that you were building an application to be run within Linux. You have already been told that you can't do that without using cross-compilation of some for, either through LLVM/Clang or through a custom GCC build. You can't avoid cross-compilation in general if your going to do OSDev. Even my kernel -- which is written in Rust -- build the compiler builtins (which is pretty much compiler-rt).

Re: Raspberry PI Bare Bones OS

Posted: Sun May 30, 2021 8:39 pm
by ssjcoder
Ethin wrote:You used your local compiler and it wasn't built for cross-compilation. Therefore, it built it with the assumption that you were building an application to be run within Linux. You have already been told that you can't do that without using cross-compilation of some for, either through LLVM/Clang or through a custom GCC build. You can't avoid cross-compilation in general if your going to do OSDev. Even my kernel -- which is written in Rust -- build the compiler builtins (which is pretty much compiler-rt).
The challenge here is to figure out how to tinker with my program/flags to make it run -- using a cross compiler is not currently something I'm looking at due to how complex it is to get it setup, how many dependencies it has, etc etc.

this quote from wiki:
When do I not need a cross-compiler?
If you create a real operating system and manage to port gcc to it, that gcc will produce the very same code as i686-myos-gcc. That means that you don't need a cross-compiler on your own operating system, because the gcc there will already do the right thing. This is why the Linux kernel is built with the Linux gcc, instead of a Linux cross-compiler.
https://wiki.osdev.org/Why_do_I_need_a_ ... ompiler%3F

Also other quote:
Problems that occur without a Cross-Compiler
You need to overcome a lot of problems to use your system gcc to build your kernel. You don't need to deal with these problems if you use a cross-compiler.

More complicated compilation commands
The compiler assumes it is targetting your local system, so you need a lot of options to make it behave. A trimmed down command sequence for compiling a kernel without a cross-compiler could look like this:

Code: Select all

as -32 boot.s -o boot.o
gcc -m32 kernel.c -o kernel.o -ffreestanding -nostdinc
gcc -m32 my-libgcc-reimplemenation.c -o my-libgcc-reimplemenation.o -ffreestanding
gcc -m32 -T link.ld boot.o kernel.o my-libgcc-reimplemenation.o -o kernel.bin -nostdlib -ffreestanding

Re: Raspberry PI Bare Bones OS

Posted: Sun May 30, 2021 9:19 pm
by nullplan
ssjcoder wrote: using a cross compiler is not currently something I'm looking at due to how complex it is to get it setup, how many dependencies it has, etc etc.
You are looking to create a freestanding cross-compiler. Therefore, the most complicated part of the whole process, getting the libc stuff working, is not even part of it. Just get your distribution's MPC, MPFR, and GMP development packages, then compile binutils, then GCC. Ought to be way easier than figuring out how exactly the distribution has misconfigured your particular host GCC.

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 2:31 am
by Ethin
ssjcoder wrote:
Ethin wrote:You used your local compiler and it wasn't built for cross-compilation. Therefore, it built it with the assumption that you were building an application to be run within Linux. You have already been told that you can't do that without using cross-compilation of some for, either through LLVM/Clang or through a custom GCC build. You can't avoid cross-compilation in general if your going to do OSDev. Even my kernel -- which is written in Rust -- build the compiler builtins (which is pretty much compiler-rt).
The challenge here is to figure out how to tinker with my program/flags to make it run -- using a cross compiler is not currently something I'm looking at due to how complex it is to get it setup, how many dependencies it has, etc etc.

this quote from wiki:
When do I not need a cross-compiler?
If you create a real operating system and manage to port gcc to it, that gcc will produce the very same code as i686-myos-gcc. That means that you don't need a cross-compiler on your own operating system, because the gcc there will already do the right thing. This is why the Linux kernel is built with the Linux gcc, instead of a Linux cross-compiler.
https://wiki.osdev.org/Why_do_I_need_a_ ... ompiler%3F

Also other quote:
Problems that occur without a Cross-Compiler
You need to overcome a lot of problems to use your system gcc to build your kernel. You don't need to deal with these problems if you use a cross-compiler.

More complicated compilation commands
The compiler assumes it is targetting your local system, so you need a lot of options to make it behave. A trimmed down command sequence for compiling a kernel without a cross-compiler could look like this:

Code: Select all

as -32 boot.s -o boot.o
gcc -m32 kernel.c -o kernel.o -ffreestanding -nostdinc
gcc -m32 my-libgcc-reimplemenation.c -o my-libgcc-reimplemenation.o -ffreestanding
gcc -m32 -T link.ld boot.o kernel.o my-libgcc-reimplemenation.o -o kernel.bin -nostdlib -ffreestanding
Are you sure you want to develop an OS, dude? I feel like your trying to take the easy way out. In OSDev, there is no libc. There is no printf or anything like that. There is pretty much nothing. Your host GCC will be useless for this task. The reason that your image was 40+ KB was because the majority of that code was host-specific and had a bunch of libc-related junk in there that you can't get rid of no matter how you spin the command line. Even if you knew all the special flags that your asking for, it would still be absolutely huge. You *must* build a cross-compiler. You do not have a choice. Until you are able to run processes in your OS and your capable of hosting GCC in your OS, you can't go without a cross-compiler setup. Period.
Now, you might be saying "But Ethin, your OS is written in Rust and you didn't need to build LLVM or Rust", and you'd be right... Except that I technically did need to build LLVM. I needed to build compiler-rt. And I also needed to use a target specification as well as build core and all the other libraries I need for my kernel to target my target triplet. So in a way, I did build a cross-compiler, just in a different way.
OSDev is not easy. If you want to make an OS, you have to do really hard work. Even if you don't want to implement an NVMe driver, a GPU driver, an ATA/SATA driver, etc., but you want that functionality anyway, you still have to build all of that. You have to write all that code yourself. We might be able to provide you snippets but you'd still need to write all the boilerplate and all the other code needed to hook it into your code and otherwise adapt it to your environment. Even if you don't want to build a cross-compiler, you have to.

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 2:37 pm
by ssjcoder
Ethin wrote:Are you sure you want to develop an OS, dude? I feel like your trying to take the easy way out. In OSDev, there is no libc. There is no printf or anything like that. There is pretty much nothing. Your host GCC will be useless for this task. The reason that your image was 40+ KB was because the majority of that code was host-specific and had a bunch of libc-related junk in there that you can't get rid of no matter how you spin the command line. Even if you knew all the special flags that your asking for, it would still be absolutely huge. You *must* build a cross-compiler. You do not have a choice. Until you are able to run processes in your OS and your capable of hosting GCC in your OS, you can't go without a cross-compiler setup. Period.
Now, you might be saying "But Ethin, your OS is written in Rust and you didn't need to build LLVM or Rust", and you'd be right... Except that I technically did need to build LLVM. I needed to build compiler-rt. And I also needed to use a target specification as well as build core and all the other libraries I need for my kernel to target my target triplet. So in a way, I did build a cross-compiler, just in a different way.
OSDev is not easy. If you want to make an OS, you have to do really hard work. Even if you don't want to implement an NVMe driver, a GPU driver, an ATA/SATA driver, etc., but you want that functionality anyway, you still have to build all of that. You have to write all that code yourself. We might be able to provide you snippets but you'd still need to write all the boilerplate and all the other code needed to hook it into your code and otherwise adapt it to your environment. Even if you don't want to build a cross-compiler, you have to.
I'm not trying to build "an OS", though that is the ultimate goal.

I'm here trying to actually boot the system into something of my own design, so current scope is bootloader not an entire OS.

While working with Intel I used fasm and was easily able to make something bootable without any of this flags non sense.

And now that I'm using Linux fasm doesn't really work out I don't know how to use it on Linux and ARM is different from Intel.

I don't see why making something bootable should be hard except that a. Designers were morons or b. They deliberately made it stupendous

Either way, I don't care.

I'm here trying to make it work without running 8 laps around the world and if that isn't an option then this "OS design" style of wasting time reading docs and trying to get the most basic things working the "not easy way" is clearly not worth my time.

In any case I will continue this side project slow paced so your input will be considered, thanks!

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 2:55 pm
by Korona
No, you are not trying to make it work without jumping through hoops, you're literally choosing to take the difficult route. Simply building the cross compiler and being done with it is the easy route.

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 3:45 pm
by zaval
when I used gcc and played with bare uboot (UEFI was too rough in it then) a couple of years ago, I used these flags for gcc. try it, maybe it'll work for you. but again, it's not for RPi, it doesn't use uboot. I can't help with it. looking at your code, it does too much as for the first run. maybe forget about "shutting down" secondary cores for a while and limit your code by plain printing something into UART for the beginning?

Code: Select all

# for 32 bit
LDFLAGS	:=	-EL -static --nmagic
CFLAGS	:=	-ffreestanding -nostartfiles -nodefaultlibs -nostdlib -O2 -static -mtune=cortex-a7

# for 64 bit
LDFLAGS	:=	-EL -static --nmagic
CFLAGS	:=	-ffreestanding -nostartfiles -nodefaultlibs -nostdlib -O2 -static -mfix-cortex-a53-835769 \
		-mfix-cortex-a53-843419 -mtune=cortex-a53
IIUC, using -fPIC for a bare metal binary is 100% fail. you have to fix up those ELF thingies to make it "PIC" before jumping to that code. Does your code do that? if no, then don't use -fPIC.

ARM isn't any different in this respect, than x86. what you are facing is the difference between "philosophies" - UNIX dudes do it this way - compile new gcc for everything - for the OS itself, for uboot, for the applications. :D For me, it also looks lame, but since I couldn't make my own compiler, and didn't want to figure why they do it this way, I just downloaded those 2.43GB of bloat from linaro and used it. Then, when MSVC for ARM finally was available, I happily forgot about gcc.

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 4:11 pm
by ssjcoder
thanks guys will read and try what has been said, within the next few days probably (busy IRL rn)

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 4:12 pm
by foliagecanine
Sounds like you're looking for something like this: https://www.cl.cam.ac.uk/projects/raspb ... index.html

As for the cross compiler, I believe you can do "sudo apt-get install gcc-arm-none-eabi" on the Raspberry Pi OS to get a prebuilt generic arm32 cross compiler.

I haven't done OSDev on a Raspberry Pi in a while, but this tutorial worked pretty well for me (up to the keyboard part). Hopefully this helps you.

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 10:20 pm
by ssjcoder
Ended up having time today to tinker with it.
zaval wrote: IIUC, using -fPIC for a bare metal binary is 100% fail. you have to fix up those ELF thingies to make it "PIC" before jumping to that code. Does your code do that? if no, then don't use -fPIC.

ARM isn't any different in this respect, than x86. what you are facing is the difference between "philosophies" - UNIX dudes do it this way - compile new gcc for everything - for the OS itself, for uboot, for the applications. :D For me, it also looks lame, but since I couldn't make my own compiler, and didn't want to figure why they do it this way, I just downloaded those 2.43GB of bloat from linaro and used it. Then, when MSVC for ARM finally was available, I happily forgot about gcc.
so I should try omitting "-fpic"? k lemme try
EDIT
same issue, though notably file was 40.0 KB (instead of 40.1 KB) when omitting -fpic flag
foliagecanine wrote:Sounds like you're looking for something like this: https://www.cl.cam.ac.uk/projects/raspb ... index.html

As for the cross compiler, I believe you can do "sudo apt-get install gcc-arm-none-eabi" on the Raspberry Pi OS to get a prebuilt generic arm32 cross compiler.

I haven't done OSDev on a Raspberry Pi in a while, but this tutorial worked pretty well for me (up to the keyboard part). Hopefully this helps you.
thanks for pointing that out!

I installed the arm-none-eabi-gcc, however, it still generated a 40.1 KB file, and that same file still hanged the OS. (exact same behaviour)

Here is the bash code that I used:

Code: Select all

arm-none-eabi-gcc -mcpu=cortex-a53 -fpic -ffreestanding -c boot.S -o boot.o
arm-none-eabi-gcc -mcpu=cortex-a53 -fpic -ffreestanding -std=gnu99 -c kernel.c -o kernel.o -O2 -Wall -Wextra
arm-none-eabi-gcc -T linker.ld -o myos.elf -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
arm-none-eabi-objcopy myos.elf -O binary kernel7.img
same source files were used.

I'm gonna tinker some more with it to see if I can find the issue.

Re: Raspberry PI Bare Bones OS

Posted: Mon May 31, 2021 11:17 pm
by kzinti
Why are you linking with libgcc? Maybe that's where the 40 KB is coming from?

Re: Raspberry PI Bare Bones OS

Posted: Tue Jun 01, 2021 12:26 am
by ssjcoder
kzinti wrote:Why are you linking with libgcc? Maybe that's where the 40 KB is coming from?
I have no idea what "lib gcc" even is.

I've been attempting to do a bare bones, strip down everything, boot of the raspi OS but apparently it takes a bunch of commands and whatnot, not really anything that I specifically want in the first place.

In any case I'm going to update you all on the status.

I messed around with qemu which seems to be able to load my .elf file in raspi2 mode, but my SD card can't seem to be able to boot into any .img files that I find online and paste into the SD card, I tried from here: https://github.com/PeterLemon/RaspberryPi

It seems that I may be screwing the actual FAT32 system of the ras pi and it simply refuses to boot anything and display anything meaningful into the HDMI besides the same old rainbow coloured gradient.

I'm gonna take a break and hope that this FAT32 system fixes itself, as at this point it's basically a dead-pi only wants to run raspbian ...

Re: Raspberry PI Bare Bones OS

Posted: Tue Jun 01, 2021 10:07 am
by kzinti
ssjcoder wrote: I have no idea what "lib gcc" even is.
Remove "-lgcc", that's telling gcc to link libgcc in your binrary.

Re: Raspberry PI Bare Bones OS

Posted: Tue Jun 01, 2021 10:11 am
by Octocontrabass
kzinti wrote:Why are you linking with libgcc?
It's required for code compiled by GCC.
kzinti wrote:Maybe that's where the 40 KB is coming from?
Probably not. The linker is smart enough to discard the unused parts of libgcc, which should be most of it.