For our C programs to work, we have to update our startup code and also the linker script.
So linker script has to be updated for BSS section placement vectors, section placement and arrow data
section placement.
BSS section is placed right after the data section in Ram, and we need to add the logic to find out
the start of BSS and end of BSS and arrow data is placed right after the text section in the flash,
so if you see this one.
Now once we have our C program, we'll have the various sections vector section at the very start of
the uh, flash memory because you have exceptions, memory mapped to this location.
So you will be having uh, the first eight uh, words will be the vector section.
Then comes your text section where your code is present.
The instructions are present.
The startup logic is present.
Then you have arrow data which is placed after the text section.
Then you have this.
This are having both load and runtime.
Both are same addresses.
Then you have the load data section which is a load location location of the data in the flash, which
has to be copied to the runtime location in the Ram.
So data is here.
And then comes BSS which is placed after the data section.
And then comes the stack pointer which is placed here.
Okay.
Now let's look into our uh script which we have.
So we have our linker script updated.
Uh, so first we have our vectors which is added in the text section.
And then you have the text from all the, all the code, all the object files.
Then after the text section we are keeping the arrow data section.
And then we have the variables assigned for uh, copying the uh data section from the flash to the Ram.
And then after this we have extra, uh, start of the base segment and end of the base segment, and
we calculate the size as well.
Now let's look into the startup code which we have.
So startup code uh so we first have the vector section.
So we are informing assembler.
This is the vector section.
And whenever the reset you start executing from the start.
So be start.
So it executes from the start.
And which is the text section.
Here we are copying first performing the startup logic where we are copying everything which is present
in the flash related to data to the Ram.
Uh, this is the logic for that.
And then we are also, uh, initializing the BSS.
Uh, we are initializing the BSS.
And if BSS is zero, then we are not performing this loop.
Uh, this zero loop.
And we are directly jumping here where we are initializing the stack pointer to the end of the Ram.
Uh, last location.
So descending stack.
And then we are just calling a main function which is not defined here, just defined in the C code.
So this is the startup code which is defined in the assembly where there is a vector uh section there
is a text section uh where we perform the startup logic.
And then we jump to the main, which is here.
So BL main is jumping to the C code from the assembly code.
So now we have three files.
One is a linker file where we have the linker uh linker script which performs section placement and
section merging.
And it also performs symbol resolution.
Then you have a startup assembly code which has, uh, the startup code to initialize various sections
and copy the logic that data to the Ram and be initialized.
The BSS set up the stack and call the main.
Now main is uh.
Now we can execute C code and let's see how we can do it.
So, uh, this is the command for executing, compiling, and generating the Elf file.
Till now, we were using assembler and converting to the object file, and then using linker and generating
the Elf file.
Now we can do it in a single command.
So using gcc I can pass c file and uh startup dot s which is an assembly file.
I can also pass the linker script using TI and it will give me the, uh, elf file.
I'm here specifying a no stdlib.
No stdlib is used to specify that do not use any standard C library, because if you do not specify
this by default, it will try to use C library.
If you want to use C library, then extra care has to be taken if you are using C library.
But because we don't have any C library use case like printf and all, we are saying no stdlib so I'm
copying.
I'm running this command.
Now I have uh, the elf file generated.
Which is an elf.
I can now verify using NM the symbols.
I can look into the symbol table and I have my vectors set up.
So this is in the text section.
And uh, all those are in the text section.
And then I have all uh the start function and the main function also present.
And I also have my Ram here.
Now let's see.
I will convert this into a binary format.
I'll run this code.
I have the binary now.
Assembly code.
If you see assembly code is placed right after exception vectors, which is 0 to 0.
The main is because we have first main uh, in the linker script.
Main is first, then is the start.
How we have the linker script.
Okay.
She is automatically taking care and keeping the main first.
This is, uh, because we have not specified two objects.
We are said merge all the text sections here and then return.
The data is placed after the flash.
So we have the in the C code we have uh.
Uh we have this is the read only which is n n is placed after the flash, after the stop of the stop,
which is the assembly code.
Right?
Stop is where startup.
If you see this is the last instruction.
So, uh, it is placed the stop.
So after the stop is where the flash is placed.
And then you have uh, r which is an initialized global variable.
It is placed at the starting location of the Ram.
R is placed at the starting location.
And then you have the base segment after the ram completes, which is uh, what is the.
Some is uninitialized and some is placed here after the uh, global data section of initialized variables
is completed.
BSS section starts now.
Yeah.
Now we will create.
We have created a bin file.
Uh, this is like of how many bytes?
To 80 bytes.
Now we'll create our flash and we will write our binary in under this.
And we'll start our chemo emulator and XP.
Now what we are trying to do is we are trying to verify what is present at the start of the, uh, this
particular location, which is start of the Ram.
And if you see this is start, uh, this values are present at the start of the Ram.
And what is present at the, uh, some which is the BSS location.
And if you see the code, so 110 four, five, six seven are present at the start of the Ram.
And this is also specified in the this thing.
Right.
If you see in the RR is present at this particular location and RR is 110 4567 and uh, some, some
is present.
This is a value which is present in the BSS which is initialized to zero.
And finally it has the result right which is adding of this ten plus 414 1516 all this.
Right.
If you add all this, it will be 33, uh, which is in the hexadecimal or this is printing in the decimal
I guess.
So yeah.
And this is the location 18, which is also specified in the symbol table.
So.
So what we have till now understood is we have started with a very basic OP code and then assembly.
Then we went into linker and functionality and then we wrote start up code for assembly copying to data
section, uh data section to the Ram.
And then we started a C program where uh, where we wrote, where we have updated our startup code to
initialize the stack, initialize the raw data.
We have also added vector exception sections, vector sections.
And then we have also copied data.
Uh, we have also initialized the raw data and all.
So this is all which is happening in background.
If you are, uh using bare metal programming you have understood all this, right?
This cannot be easily understood if you are doing it on C programming.
So in your C programming, which we have seen in your OS, if you are using Linux OS internally, linker
is doing a lot.
So whatever we did using this right, you were doing linker and all you are linking multiple object
files.
So I just wanted to explain you the reason, uh, how it works, how, uh, processor works, how its
instructions are executed.
So I explained you about all these, uh, things.
The way I execute.
I have shown you the bare, uh, metal programming, the assembly programming and C programming, how
we started from assembly to C and all because I just wanted to understand how it works, how processor
executes instructions.
And we have, uh, we are able to understand now in a very good manner, like how a C code is executed
and what is the startup code, who is adding the startup code?
What is the functionality of linker?
All this we are able to understand.
I think now we can easily move to Elf and now we can understand what is an elf, why we need elf and
all.