Is it possible to force the compiler (with a directive or something) to store a specific part of the code in a predefined area in the memory? What I want to do is to be able to calculate a checksum of some specific functions in my code, so I later can prove that they are unchanged since the last build. My thought is that if I know in which memory area these functions are located then I can simply calculate a checksum of this area. Any ideas, someone?
What I want to do is to be able to calculate a checksum of some specific functions in my code, so I later can prove that they are unchanged since the last build. You can't do that. They may "change" eventhough they are "the same" because some variable is added elsewhere in the program which makes the linker change the address of some of the variables used by "unchanged" code. Erik
The linker has a number of directives for locating code in specific places. You could probably perform your test earlier, say on the object files, rather than wait until the code is located and loaded -- unless you're trying to do this test at runtime.
This sounds like a strange idea. I completely agree with erik. You have a much better chance of verifying code integrity by calculating checksums of source files. Why don't you describe the actual problem? Then we might be able to suggest something. - mike
Remember that a checksum is a weak form of error detection. It detects single bit errors and half the double bit errors. EDAC schemes use syndromes and they usually use any apriori knowledge of the input data and error sources. Your testing integrity of a function. Why not define all(some?) possible inputs tablualte the correct outputs and write a test fumction which calls the function under test using those test vectors and checks the outputs against the table. It's a weird idea, there are a lot of weird ideas. My point is to not just blindly apply some device like a checksum, think specifically about your problem and use your imagination.
Remember that a checksum is a weak form of error detection. It detects single bit errors and half the double bit errors. The OP is not concerned with errors (I hope he is, but that is not what his post is about), but with changes. I guess chanage control that fail 1/256th of the time is good enough, so what if now and then you do not record a change. Erik
Ok, I shall try to explain my problem. At my company, we have some products to which we release new firmware up to four times per year. However, there is a part of the code functionality that is associated with legislation, and this part of the functionality (code) has to be certified against authority. When we deliver a firmware, the regulation says that we must be able to show that the code has the same checksum as the one we used for certification. That is a big problem for us; because we have other features in our product, not dependent on regulations, that is continuously updated, this will change the checksum of the whole source code build. So my idea was if it is possible to in some way just calculate a checksum of the code parts associated to the legislated certification. I'm not trying to track errors or anything; I just want to be able to show that these code parts are unchanged since certification. Thanks for all answers so far… / Rasmus
Hello again... I thik this can help me: http://www.keil.com/support/docs/2215.htm What do you think, anyone? / Rasmus
I thik this can help me: http://www.keil.com/support/docs/2215.htm That will be required but you may still get in trouble because of the linker moving variables. The linker will have an affect regardless of where you locate the critical code. I do not know how memory squeezed you are, but there is one solution to keeping objects constant. EACH and EVERY (global or local) variable in the critical area must be global this is raquired regardless of method and declared as extern ONLY my method below. These variables must be permanently located at absolute addresses in an assembler module. There are means (I think) for locating variables at fixed addresses in C, but the above assembler method serves me for fixed location variables. Erik
I think you should design the certified part of the program as a separate binary chunk of code that doesn't need to be changed when you modify the rest of the application. This means that the binary chunk should always be located in the same memory area and it should have a clearly defined binary interface (code entry points, shared data structures) and execution environment so that the main application can communicate with it. Then checking the integrity of that binary code becomes straightforward. I'd also like to reiterate the point that a simple checksum doesn't guarantee that the code is unchanged. A cryptographically strong hash does. Regards, - mike
Erik, I'm afraid I don't quite understand you. Our source code is loaded into a flash EEPROM and executed from there. Variables are allocated space and stored in the RAM memory, so, how can that affect a dedicated section in the flash… or am I completely lost now… late afternoon J If I look in the target set up, it looks something like this:
FCODE(0x10000-0x4FFFF),FDATA(0x100000 - 0x130000)
Rasmus, there is some confusion here. You are referring to your source code being loaded into flash EEPROM. But 'source code' usually means text files with code in the C programming language, which are subsequently passed to a compiler and linker to obtain executable code, which is in turn loaded into flash EEPROM. So either you implemented some kind of high level language interpreter in your application or 'source code' means something different. It seems that Erik assumed that the code you were referring to was in the form of library files (*.LIB) to be fed to the linker. But from your posts it looks like the code is in a different form, and I have no idea what that form might be... - mike
It seems that Erik assumed that the code you were referring to was in the form of library files (*.LIB) to be fed to the linker. Mike has it almost right I thought .lib or .obj. Variables are allocated space and stored in the RAM memory, so, how can that affect a dedicated section in the flash When the linker process an object file, it will modify the instructions with the actual address of the variables as assigned by the linker. If a module outside the "protected code" is changed, the addresses assigned to the variables in the "protected code" will most likely change making the flash image different. Erik
Yes, sorry, I was expressing my self incorrectly. This issue is about calculating a checksum of the executable code when loaded into the flash memory. The purpose is to be able to in runtime ask the firmware to calculate and return the checksum (via the user interface). So, Erik, I still don't understand, if I tell the linker, variable data shall be stored in this area (RAM) and the code shall be stored in that area (FLASH) how can then variables outside the "protected code" affect the protected code area in the flash? My thought was that only executable code is stored in the flash, not variables, and that is also what I want to calculate the checksum on, the specific area of executable code in the flash. This is my L166 locate settings: NDATA(0x130000-0x133FFF) , NDATA0(0x130000 - 0x133FFF), FCODE(0x10000-0x4FFFF), FDATA(0x100000 - 0x130000), FDATA0(0x100000 -0x130000), HDATA(0x100000 - 0x130000), FCONST(0x10000 - 0x4FFFF), IDATA(0xF800-0xFDFF) , IDATA0(0xF800- 0xFDFF), ICODE(0x10000-0x4FFFF), NCONST(0x10000 - 0x13FFF) So I can't see how changes in data sections can affect the code sections.
So, Erik, I still don't understand, if I tell the linker, variable data shall be stored in this area (RAM) and the code shall be stored in that area (FLASH) how can then variables outside the "protected code" affect the protected code area in the flash? OK, let's try an example your checksummed code use a RAM variable called CSram. The linker locate it at, say 0x43. so the linker modify the code mov a,CSram = E500 (00 becauee unknown) to E543. Now you modify your "flexible" code and add some variables, one of which the linker locate at 0x40. this moves CSram to 0x44 so the location in the checksummed code that used to read E543 now read E544 thus, although the code is the same the hex image is different. Erik
Ok, I understand now, examples are great! (I don't understand why it took me so long…) But what if I do as you suggested in a earlier post,These variables must be permanently located at absolute addresses in an assembler module. By the way, I am still not so familiarly with the platform and the environment. I have problems with finding out the address area for the external flash EEPROM. Do you have any idea of how I can find that out? Anyway, thanks for your help / Rasmus