How can i read and write a bootloader program from an application section code.

Go To Last Post
32 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am working on Arduino UNO having atmega328P.

I want to read the bootloader contents by using application code.

If it is possible how can i do that.

 

Thanks in advance.

 

 

Nitin

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitin74 wrote:
I want to read the bootloader contents by using application code.

Why do you want to do that?

 

What is your goal here?

 

http://www.catb.org/esr/faqs/smart-questions.html#goal

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

nitin74 wrote:
I want to read the bootloader contents by using application code.

Why do you want to do that?

 

What is your goal here?

 

http://www.catb.org/esr/faqs/smart-questions.html#goal

specially as the bootloader can be found online.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's easy to read any of the flash in an AVR:

typedef const __flash uint8_t flash_byte;
typedef flash_byte * flash_ptr;

	uint32_t val = 0;
	for (flash_ptr addr = (flash_ptr)0x1234; addr < (flash_ptr)0x3456; addr++) {
		val += *addr;
	}

Basically you create a  "const __flash type *" pointer then read through it.

 

If using C++ (as in Arduino) you can't use __flash so the alternative would be something like:

#include <avr/pgmspace.h>

	uint32_t val = 0;
	for (uint16_t addr = 0x1234; addr < 0x3456; addr++) {
		val += pgm_read_byte(addr);
	}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello awneil sir,

In my application i required to have my own bootloader which i will be programming from application section , depending on my code's certain conditions.

So I need this functionality for that.

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello clawson sir,

 

Thank you for the code.  but the output is coming all zeros for all addresses.

I am using atmel studio with USB asp programmer for programming arduino kit by ICSP header. Also Arduino kit is also connected by usb for powering ON.

 

Is their anything for writing the flash code too?

 

Thanks

Last Edited: Thu. Jun 18, 2020 - 07:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On ATmega328, you can only write to flash from the "bootloader section."  An application can potentially write to flash by calling a "helper" function in the bootloader section.

For the application to read the bootloader section, the Boot Lock Bits have to be set appropriately (an Arduino Uno defaults to "boot NOT readable by application.)   See section 28.1 of the datasheet ("Memory Programming")

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The bootloader is protected, so you can’t write over it in your application. As well, only the bootloader can write to the application flash at run time.

Read the datasheet where this is explained.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello westfw sir,

 

Yes you are right. I think that helper function is do_spm. I have tried it  and yes it writes in memory (may be that memory is between application code and bootloader code. i have not confirmed it yet ).

 

For "Boot Lock Bits have to be set appropriately " , an Arduino Uno defaults set value to 0xFF (in my case). But 0xFF corresponds to unlock state where we can read the memory. But here I am getting 0xFF for all memory addresses. 

 

And 0xFC corresponds to Locked bootloader, is it correct?

 

thanks in advance

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The arduino “burn bootloader” command *used* to unlock everything and erase the chip, upload the bootloader, and the reset the lock bits to 0f.

https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L70

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello sir,

Thats fine.

But I cant control this Arduino sequence.

My question remains how i access the bootloader contents??

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitin74 wrote:
My question remains how i access the bootloader contents??
A pgm_read_byte or a dereference through a __flash * pointer should work. If it didn't you were probably doing something wrong!

 

Still not entirely clear WHY you would want to read the bootloader opcodes from an app but I'm sure you must have some reason.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Still not entirely clear WHY you would want to read the bootloader opcodes from an app but I'm sure you must have some reason.

Indeed.

 

@ nitin74 : hence the question in #2:  if we knew what you were trying to achieve - ie, what your actual goal is - we might be able to suggest ways to achieve that.

 

Again: http://www.catb.org/esr/faqs/smart-questions.html#goal

 

See also: XY Problem

 

https://en.wikipedia.org/wiki/XY_problem

 

#XYProblem #GoalNotStep

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Jun 19, 2020 - 09:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would take a look at the Optiboot source code itself( I think it's in C or C++) or the hex generated by it. I use AVRstudio 4 and can view the hex values of my boot loader in memory window as well as the location. Was very helpful in writing my boot loader. I think AS7 has something like that but not sure. I also only code ASM which may produce different results when trying to troubleshoot/debug. Not sure if you're trying to modify the behavior or what... that clarification would be good to know. Good luck!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You mean you just want to see the Asm generated when Optiboot is built? Wouldn't the C compiler and the -save-temps option be a much simpler/easier way? Or the .LSS file? Or even the .hex for Optiboot disassembled by avr-objdump?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello sir,

 

i am displaying 16 bit number. Since val is 32 bit so i get 8 digits for one memory location data.

The contents which I am getting is 00000001 and so on and which then increments to 00000002 ( after more than 30 bytes (30 not an exact number)) and so on ..

 

So yes pgm_read_byte and  __flash * pointer is not working for me unfortunately. What are reasons behind it.?

 

I need to access bootloader contents because my goal is to make bootloader secure.

 

Thanks

Last Edited: Tue. Jun 23, 2020 - 10:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Plexd,

 

Ok i will see it  and come back soon.

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitin74 wrote:
I need to access bootloader contents because my goal is to make bootloader secure.

Eh?!?!

 

That makes no sense at all

 

Security is not something that you can just bolt-on as an afterthought!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Jun 23, 2020 - 10:55 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello AWNEIL,

Yes you are correct. for Security I need to start from basic. For it only, I am just exploring this boot loader thing.

 

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all,

some basic questions..I am missing some vital links, so wants to clear them.

1.) How avrdude distinguishes between a bootloader and application program during programming?

2.) How "boards.txt" is used for programming?

 

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) it doesn't 

2) boards.txt just has details like what to set the fuses to and things like that. (easiest way to find out is simply to read the details repeated in each board section) 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello sir,

 

thanks for clarification . but some more doubts their..

for

1.)  if it doesn't, then does it simply program the memory depending on the addresses in hex file and do the relevant settings?

2.) If I change some values in the board file, it will affect at the time of programming?

 

Also,

I have just came across the spm instruction by using which we can access bootloader memory contents by reading and writing it. It makes use of logic consisting of executing first step of spm instruction and then starting timer and then searching the opcode of out spm instruction.  Then it finally write spm instruction at the end of memory. Can you clarify it. I am not able to understand it clearly.

 

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

2) boards.txt just has details like what to set the fuses to and things like that. (easiest way to find out is simply to read the details repeated in each board section) 

 

Does AVRdude even use boards.txt? I thought it was used by the Arduino IDE, not AVRdude.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BrendanP wrote:

clawson wrote:

2) boards.txt just has details like what to set the fuses to and things like that. (easiest way to find out is simply to read the details repeated in each board section) 

 

Does AVRdude even use boards.txt? I thought it was used by the Arduino IDE, not AVRdude.

 

 

The IDE uses boards.txt to build the appropriate avrdude command lines, which it then executes. avrdude then uses its own config files (global and possibly local too).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitin74 wrote:

 

1.)  if it doesn't, then does it simply program the memory depending on the addresses

exactly. All avrdude does is program hex data. It's the address fields in that which say whether it is positioned at app or boot location. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello obdevel,

 

If Arduino IDE uses boards.txt, then is it possible that if I changes lock bits values in txt file, its effect will appear when I program my code through IDE ?

 

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitin74 wrote:

hello obdevel,

 

If Arduino IDE uses boards.txt, then is it possible that if I changes lock bits values in txt file, its effect will appear when I program my code through IDE ?

 

thanks

 

If you change the lock bits / fuses in the boards.txt file, those changes will be applied if you program the ATMega with an ICSP programmer. (not via the bootloader).

 

If you're using the serial UART connection (and the bootloader) then the fuses won't change. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello BrendanP,

thanks for the clearing the doubt.

 

Hello clawson sir,

regarding your quote:

It's easy to read any of the flash in an AVR:

typedef const __flash uint8_t flash_byte;
typedef flash_byte * flash_ptr;

	uint32_t val = 0;
	for (flash_ptr addr = (flash_ptr)0x1234; addr < (flash_ptr)0x3456; addr++) {
		val += *addr;
	}

why plus sign is their in "val += *addr;"  ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitin74 wrote:
why plus sign is there in "val += *addr;"  ? 

Because that example comes from code to calculate/verify a checksum?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nitin74 wrote:
why plus sign is their in "val += *addr;"  ?
As Andy says it was just showing an example of what you might do with the bytes of flash data (otherwise why bother reading it?). So I just did the simplest of "checksums" by simply adding each byte I read into a running total.

 

Just out of interest why are you trying to read the data anyway?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
why are you trying to read the data anyway?

He did give a reply to that question in #18 - not sure it made any sense, though ...

 

frown

 

EDIT

 

sorry - his reply was #16.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Jun 29, 2020 - 09:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

nitin74 wrote:
I need to access bootloader contents because my goal is to make bootloader secure.
Is this simply about checking the bootloader lock bits to verify that when set they DO prevent LPM in that area ??

 

If so then note that NO lock bit is really secure. It costs about $500 to get the lockbits unlocked for anyone who wants to read the code out of any part of an AVR. Lockbits may prevent hobbyists who are just "snooping" but if you have a commercial competitor who wants to clone your product they will likely pay the $500 and get a copy of your entire code anyway.