Thanks David. I think your main concern was about boatload upgradability. My assumption was that in the field you would NOT upgrade it. From what I have heard, most folks lock the flash sectors of the boot loader before shipping. This is a larger question for the group. How do others feel about boot loader upgrade. Regarding your upgrade procedure below, if a boot loader upgrade fails in step B, the thing would become a brick.
You question about AIDC revert is valid. I was assuming that during the upgrade process, the utility or person doing the upgrade would copy the AIDC from the device and store it. Then if the upgrade went wrong as we describe below, it could re-load it onto the device. In your confusion below, your description sounds perfect. The AIIC would always be a runnable image. And it would sometimes jump into the AIDC (if if was there and the unit was not upgrading). The paragraph that confused you was discussion two options for how the AIDC would eventually run… would it be run by the boot loader directly (after validate both the AIIC and AIDC were present) or would it run the AIIC and have the AIIC responsible for validating and running the AIDC. In this design, I chose the latter model where the boot loader will only run the AIIC (which is a complete image). It would be up to the AIIC to start the AIDC (which can’t run without the matching AIIC). Paul On 6/24/16, 9:05 AM, "David G. Simmons" <[email protected]> wrote: >Comments/questions in-line. > >> On Jun 22, 2016, at 7:58 PM, [email protected] wrote: >> >> Here is a high level functional spec for the split image feature. It >>include a motivation, overview of design decisions, and a set of >>functional changes that need to happen. I’d love to get feedback if you >>are interested. >> >> Its not quite a complete design, but there are still a few unknowns to >>work out. My though is to get feedback through this week and start the >>implementation next week. I was thinking about starting with the >>Bootloader Changes, then the Newt Changes, then writing the loader_app >>and new newtmgr commands. Anyone up for helping? >> >> Paul >> >> >> Split Image Bootloader (SIB) >> >> This document describes the split image bootloader design. >> >> Status >> >> This document is currently draft an anxiously awaiting review. >> >> Motivation >> >> The goal is to create an application in two pieces to fit into two >>image banks such that one piece would contain the bluetooth stack and >>firmware update application and the other would contain the customer >>application (that’s the goal, but it would be defined generally to allow >>any split). These two are linked together with a special property that >>the upgrade app (also called loader_app below) could run without the >>customer app but not vice versa. To give these names I call the >>independent one the AIIC (Application independent image component) and >>the customer app the ADIC (Application Dependent Image component). >> >> Consider this example, two 112k flash banks which we want to store a >>bluetooth application. Assume the following code sizes: Application size >>32k, Bluetooth stack size 64k, Upgrade code size 16k. With two >>independent app images, each would be 112k filling the available >>sectors. However, if we split the image we would have an upgrade image >>of 80k and an app image of 32k (since it uses bluetooth and upgrade from >>the AIIC) leaving tons more space for sophisticated applications and >>more space for the upgrade as well. >> >> We decided to create this split image as a pair that are linked >>together during the build process. There will be no dynamic bindings >>like SWI or function table or anything like that. The goal is not to >>separate the OS/stack from the app, but just to be a bit more efficient >>about duplicating the large components like bluetooth. Thus, when up are >>updating one of the split images, you MUST update the other. Splitting >>the image makes this “safe" as there will always be a bank filled with >>an image that is capable of performing an upgrade. >> >> You can see some discussion below from Contiki and NUT below about how >>they did the same thing (although some were later replaced with dynamic >>loading) >> >> High Level Operation >> >> The basis principle is to create two image components that make up a >>single image. One component would include an image loader and the >>components required to load the image (e.g. bluetooth or serial). The >>other component would include the remainder of the application. A small >>bootloader would verify the two images and boot the one that was >>relevant. >> >> There are three image components to the SIB: >> >> 1. A bootloader >> 2. An application independent image component (AIIC) >> 3. An application dependent image component (ADIC) >> >> There are four flash regions required for the SIP >> >> 1. the boot image region (BIR) >> 2. the primary image region (PIR) >> 3. the secondary image region (SIR) >> 4. a scratch area region (SAR) >> >> The bootloader is intended to be programmed at manufacturing and will >>not be reprogrammable in the field. It is always loaded into the BIR. > >Is there a fall-back position to be able to load a new bootloader? There >are instances where a new bootloader may be needed (bug fixes, major >upgrades, etc.). Return to Factory for bootloader upgrades will be >expensive and difficult for large-scale deployments. Even for small >deployments. > >> >> The AIIC has the ability to upgrade itself and download new AIIC or >>ADICs into the SIR. The AIIC always runs from the PIR, but can be loaded >>into the SIR and copied to the PIR by the bootloader. >> >> The ADIC always loads and runs in the SIR. The ADIC cannot upgrade >>itself (well it may have code to do so, but has no-where to write a new >>image since it uses the SIR and requires the PIR to run). >> >> The AIIC and ADIC are not independent components. An upgrade must >>upgrade both of these components. That is, they will be statically >>linked to run as a single unit. However, the AIIC will be linked to be >>able to run without the ADIC in order to perform an upgrade of the AIIC >>and ADIC. >> >> The scratch area region (SAR) is used when swapping AIIC images to/from >>the SIR to the PIR. >> >> Requirements >> >> The following lists the user requirements for the booting of split >>images. >> >> 1. Use the Nordic Soft Device as part of the AIIC >> 2. Update the ADIC with only an AIIC present >> 3. Update the AIIC with only an AIIC present >> 4. Update the ADIC with the AIIC and ADIC present >> 5. Must support protection of system to ensure that only approved >>images can be loaded on device >> >> Upgrade Procedure >> >> An upgrade would work as follows. >> >> 1. An upgrade would trigger a reboot into AIIC-mode >> 2. The bootloader would detect AIIC mode and run the AIIC in >>independent mode >> 3. The AIIC would download a new AIIC into the SIR and restart >> 4. The bootloader would copy the SIR AIIC into the PIR and boot the >>PIR AIIC >> 5. This new AIIC will detect absense of a SIR image and download an >>ADIC into the SIR. >> 6. The system will restart and the bootloader will run the ADIC. >> >> Fallback Procedure >> >> The following would list potential fallbacks during failed upgrade >> >> 1. If the AIIC in the PIR fails to download a new AIIC, it could >>always download the old ADIC into the PIR to resstore behavior. >> 2. If the AIIC is able to download a new AIIC but the new AIIC >>doesn't run, the bootloader could fallback to the old AIIC (since it >>swapped them) and the restore the old ADIC. > >From whence would it get this old ADIC? If I make changes to the AIIC and >the ADIC, recompile and deploy them, the old AIIC (on the host) and the >old ADIC (on the host and the device) are blown away. While the old AIIC >is still present on-device, the old ADIC is no longer present on-device >or on-host, and so cannot be restored. If the old ADIC is archived as >part of the build process then this may be possible, but then we have >versioning and “how many old ADICs do we archive?” problems. Also, since >ADICs are AIIC-dependent, we have to archive them as pairs. > >> 3. if the new AIIC loads and runs, but is unable to download the new >>ADIC, it could download the old AIIC and restore the old ADIC > >See above. > >> >> Out of Scope >> >> 1. Use of the Nordic Bootloader. Current design will replace the >>nordic bootloader. >> 2. Binary Bluetooth stack image to faciliate certification. This is a >>separate issue and not considered. >> 3. More that two image regions. There may be use cases to have more >>than two image regions. For example, there could be one AIIC region and >>two ADIC regions with different applications liked against the same >>AIIC. An example would be game1/game2. We will not support this today >>and do what our simple bootloader does which is to look at two regions >>(PIR and SIR) >> >> Current Design Discussion >> >> Here are some tradeoffs considered during the design phase. >> >> Versioning >> >> How do we differentiate between the different pieces of a split image? >> >> There are several places in the system that need to do this. To >>bootloader simply needs to know whether an image is directly bootable or >>not. >> >> The AIIC needs to determine whether it and the ADIC are a perfect match >>since symbols are pre-linked between them >> >> The user (via newtmgr) needs to be able to identify this package as a >>single UniqueName. >> >> The solution is desribed below. >> >> Starting an Application Image >> >> We have a design choice where the AIIC sometimes runs without the ADIC >>or the ADIC and AIIC may neen to be run together. There is an >>architecture decision about how this happens. Here are some choices >> >> In all cases, the bootloader can read the preferences like it does now >>(from FCB or NFFS). In all cases, the AIIC needs all the net_mgr code >>and bluetooth (or serial code) to perform an image update of the SIR. >> >> Split Image Aware Bootloader >> >> In this case, the Bootloader looks at three possible image types >>(stand_alone, split_indep, split_app) for each region and determines >>what it allows to copy or run. If would need additional (from what we >>have now)logic to validate that the split image components match and >>then run the appropriate one depending on whether they are both present >>and valid. >> >> For this model, the bootloader must understand the split image concept >>and must perform the validation of the component parts. It would make >>sense here (I think) for the bootloader to boot directly to the main of >>the AIIC or ADIC depending on whether they were both valid and the >>status of the boot request (whether the user wanted to boot the AIIC >>only). > >I’m confused at this point. Up top now, I was assuming (perhaps >incorrectly) that the AIIC was a runnable application that is started by >the bootloader. That it must always be runnable. The ADIC is a separate >runnable application that DEPENDS on the AIIC and may, or may not, >actually be run. From this, it sounds like the AIIC may, in some >instances, not be started as an application itself but that the ADIC >would be started and simply reference the AIIC for BLE, console, or other >library functions. In the second case, how would an upgrade, where the >AIIC succeeds and the ADIC fails, ever work? If the AIIC is not started >by the bootloader because the ADIC is the runnable app, then … > >> >> This method has the advantage that we only perform the security checing >>in the bootloader. It also means that we don't have to do any startup >>magic in the AIIC to decide whether to run the AIIC main or look for and >>run the ADIC main. Of course that same code would happen in the >>bootloader which is not-upgradable. > >I do still have some heartburn about a non-upgradeable bootloader. The >following may be out of scope for this proposal, but since it involves an >AIIC location, it might need to be considered. > >Here’s a scenario for an upgradeable bootloader: > > 1) Bootloader is signed with a SHA or PKI from a host computer — only >bootloaders signed with this key will be accepted except over direct >serial/jtag connection. If you have physical access to the device, you >win. This also allows a new host to ‘take over’ responsibility for >delivering bootloaders to devices by providing a new bootloader with a >new SHA/PKI key. > 2) new bootloader image is sent to the device and stored in SAR — could >be stored in SIR > a) new bootloader key is checked against current bootloader > key. If >keys don’t match, new bootloader image is erased otherwise continue > b) Keys match, so new bootlaoder is written to PIR and device > reboots >to new bootloader > c) if boot to new bootlaoder in PIR succeeds, PIR region is > written >to BIR and reboots — we have successfully updated the bootloader > d) if boot to new bootloader in PIR fails, reboots to old > bootloader, >and PIR is erased. > >This has the advantage — by first loading the bootloader into SAR for key >validation — of ensuring that a rogue bootloader does not wipe out an >existing AIIC/ADIC pair. It required 3 reboots to field-upgrade a >bootloader, but it maintains system integrity. Using this method, >bootloaders could be updated over bluetooth as well, as long as the keys >match, making filed upgrades of bootloaders possible. > >Anyone paying attention will note that this is eerily similar to the AIIC >upgrade procedure. :-) > >> >> Pros: 1. no security code in the AIIC 2. simpler linking of AIIC and >>ADIC. In this case, the AIIC would be a stand-alone linked-program and >>the ADIC would be special linkage with 3. more rigid >> >> Independent Bootloader >> >> In this case the bootloader looks at two possible image types >>(runnable, non-runnable) in each region and determines what it is >>allowed to copy and run. It does not need logic to "match" the split >>image components. >> >> In the stand-alone image case, the bootloader would look at the boot >>preference and try to validate, copy and run the image specified. This >>is no different than today, except that it would ensure that the image >>that it was asked to run is "runnable". >> >> In the split image case, the bootloader would look at the boot >>preference and try to validate, copy and run the image specified, This >>is no different than today, except that it would ensure that the image >>that it was asked to run is "runnable". >> >> This looks like the easy approach, as the bootloader would be identical >>for split images and dual-images. However, it would mean that the AIIC >>image would have to lauch the ADIC image as part of its startup. >>Depending on what information is passed to it from the bootloader, it >>may have to re-compute the security of the ADIC, and also understand the >>flashmap etc. Its likely that the AIIC would link-in many of the same >>code as in the bootloader. >> >> Pros: 1. Simple bootloader 2. Easily support dual and split image 3. >>more flexibility in AIIC for dual-image behavior (i.e. this allows >>future models to use syscall or linked or something else). it would also >>allow more flexibility for compatibility between split images. >> >> Bootloader Decision >> >> The decision moving forward (for now) is to use the independent >>bootloader model and have the AIIC validate the ADIC and run it. For >>now, we'll do this through duplicating the authentication code and >>public key code from the bootloader. This design will proceed with >>anindependent bootloader >> >> Linker Magic >> >> To build this split image, the following steps will be taken. >> >> 1. The AIIC image will be built and linked to run in the PIR. If this >>succeeds (no unresolved externals and fits into the memory). This is a >>normal linkage and guarantees that we have a stand-alone image with no >>unresolved externals. >> 2. We will run a command on the AIIC.elf file to generate a list of >>external symbols that are defined. For example, we may do nm -g >>--defined-only aiic.elf which will generate somethimg that has a list of >>symbols with their addresses. >> * 0000db90 T base64_decode >> * 0000dac4 T base64_encode >> * 0000db60 T base64_pad >> * 00015000 T ble_att_clt_rx_error >> * ... >> 3. We will remove a few key functions from that list depending on the >>decision for the bootloader above that we need to repeat in the second >>image. >> * main(), etc. >> 4. We will parse this output and generate linker command file >>split_app.ld like this >> * base64_decode = 0000db90 ; >> * base64_encode = 0000dac4 ; >> * ... >> 5. We will include this file as part of the linker script before the >>library includes. INCLUDE(split_app.ld) >> 6. The linker will then use the existing symbols definitions from the >>AIIC to build the ADIC. >> >> This has the following benefits: 1. The AIIC will always be runnable >>(it will always have exactly what it needs and no more) 2. The ADIC >>image will be complete as well. It establishes a rule for building >>independent and dependent images >> >> Drawbacks: 1. There is limited control over the size of the AIIC. You >>would have to tell the AIIC linker script to include stuff that was not >>used to balance size between AIIC and ADIC. 2. Its not clear where >>unused global variables will go. Will this force all global variables >>into the AIIC? 3. Individual packages will be split between ADIC and >>AIIC. >> >> Build Process >> >> The question I am investigating is how to formulate this in the newt >>build process. Here are two alternatives. >> >> Single Target build >> >> I was thinking that I would have a single target to produce both of >>these image components. The target would still have one bsp, one build >>profile, but I would define a new token for the target called >>loader=xxx. This would define the loader AIIC that would go into the >>first image bank, and if “loader" was defined, the app would be linked >>to run in the second image bank. Thus, if I were building a bluetooth >>app called foo, I would set loader=AIIC (contains upgrade and bluetooth) >>and then set app=foo. If “loader” was not defined, I would ensure the >>newt tool would do a complete build of foo and link it into the first >>image bank. >> >> Separate targets >> >> The alternative would be to have two separate targets. The ADIC target >>would have to reference the AIIC target and know that it was being built >>to be dependent on that bit. In this case, the AIIC target would be >>build as normal with no changes to the build system. Then the ADIC >>target would have to have a new tag that said that it was dependent on >>the other target. For example, in the app:foo target descriptor it would >>say split_image_dep=AIIC. This would cause newt to perform some special >>processing of the AIIC elf image, and ensure that we link the foo ADIC >>app to run out of the second image bank and reference common functions >>in the first image bank. >> >> In either case, the application will be build as a split image and will >>contain two elf files. One file will be the Application Independent >>AIIC) part, and another will be the application dependent (ADIC) part. >>These will both get converted to image files by newt create-image. >> >> Target Decision >> >> My thoughts are that IDEA1 is the better of these two. It would allow >>newt to be split-image-aware during create-image and during download and >>debug. This design will proceed with a single target build >> >> Image Verification >> >> We need a way to prove that the two images are indeed mates. Since the >>ADIC is essentially statically linked to the AIIC, the AIIC must be bit >>for bit exactly what the ADIC expects for code to run properly. >> >> To accomplish this requires a slight modification to the current >>design. Today each of the images has a SHA checksum that is used to >>validate that the image is unmodified from build time. >> >> The SHA in the form of a TLV that is added to the end of the image. >> >> AIICs will not change. Its SHA will be computed over its image and >>appended as it is now. >> >> When ADICs are build, their SHA checksum will be computed over the AIIC >>and ADIC image. This serves two purposes. First when the AIIC wants to >>run and ADIC it can verify 100% that the ADIC was meant to run with the >>exact AIIC image. Second, a bootloader that gets an ADIC image, will not >>run it since its SHA will not match (computed only over its image) >> >> Split Image Upgrade State >> >> It may take several system boots to perform a split image upgrade. >>State needs to be communicated between these boots. State will be >>communicated via a sysconfig variable. >> >> when newtmgr initiates and upgrade of a split image, it will set the >>sysconfig split_state to AIIC and then reboot the system. Upon >>rebooting, the bootloader will boot the AIIC which will see the >>split_state and run its internal application (rather than booting ADIC). >>In this state, new_mgr can erase the second image slot and download a >>new AIIC. Once complete successfully and the new AIIC is verified (SHA), >>the current AIIC will set the split state to AIIC and tell the >>bootloader to swap and run the alternate AIIC (in test mode) and reboot. >>When it reboots into AIIC mode, the newtmgr can check to ensure the >>right AIIC is loaded and, commit it (non-test-mode) then load the ADIC >>into the bank 2. Once loaded, it will set the split_state to 'ADIC'. >> >> Functional Spec >> >> This section describes the functional specification for the Split Image >>Bootloader. Its mean to describe the set of changes to each system >>component, without getting into the design of each component. >> >> Image Header >> >> The image header will be augmented with another flag in the ih_flags >>field: >> >> IMAGE_F_DEPENDENT >> >> >> This will signify to the bootloader that this is not a runnable image >>and that this image cannot be copied into the PIR of the flashmap. >> >> This will signify to the AIIC image that this image may be its co-image >>(if its version matches as well). >> >> When building an AIIC, the SHA will be calcualted over the contents of >>the AIIC image. >> >> When building a ADIC, the SHA will be calculated over the contents of >>the AIIC and ADIC. >> >> Bootloader/Boot Util >> >> The bootloader will be augmented to check the IMAGE_F_NON_BOOTABLE >>flag. It will not copy a non-bootable image into the PIR and will not >>boot a non-bootable image. >> >> If a non-bootable image winds up in the PIR, and there is a valid >>bootable iamge in the SIR, the bootloader will swap them (This should >>not happen) >> >> The bootloader will NOT verify SHA or PKI on non-bootable images since >>it won't boot them. It will only verify these on bootable images. >> >> NOTE: These changes are minor and intended to allow the bootloader to >>be simple and compatible with dual images or split images. >> >> The bootloader will not know about the split image scheme, but only >>know about two types of images, bootable and non-bootable. >> >> The bootloader current stores version numbers in the sysconfig. We can >>still use this method (but only boot images that also have BOOTABLE), >>but time permitting, I will make the sysconfig in the bootloader rely >>only on the hash values of the image TLV instead of the verison number. >>This would remove dependency on the uniqueness of the version number. >> >> boot Util Library >> >> The bootutil library will be augmented to allow the following. These >>may be used by the loader_app . >> >> 1) Ability to verify a combined AIIC and ADIC together. 2) Ability to >>boot into a ADIC >> >> Newt >> >> Newt is the system build utility and package manager. >> >> Target Descriptor >> >> Newt will be augmented with a additional field in the target. >> >> loader_app=@apache-mynewt-core/apps/loader >> >> >> This will tell newt that it is to split the image loader from the >>application and create a split image. >> >> Newt Build >> >> If loader_app is not defined in the target, the build will proceed as >>it does today. If loader_app is defined, the following additional steps >>will be taken: >> >> 1. Before the build of the app, newt will build the the loader_app >>application (with the same rules as the app). One exception is that the >>for loader_app it will use the primary.ld linker script, which links to >>the first flash bank for that target. The loader_app build components >>will be placed in the bin/<target>/apps/<loader_app_name> directory. >> 2. Then, newt will generate an loader_app.ld file which contains the >>address of all the symbols in loader_app_name except for a few key ones >>like main, startup and maybe a few others which will be removed so they >>are duplicated in the main app. >> 3. Now newt builds the app as before, but if loader_app is defined, >>uses the secondary.ld linker script. >> 4. This linker script has an INCLUDE(loader_app.ld) directive to use >>the addresses for the components already included in theloader_app. >>(NOTE: Not sure about paths and how to get the app to find the path to >>the other directory. >> >> Boot code will still be built with a special bootloader linker script. >> >> Newt Clean >> >> Will be expanded to ensure it cleans the loader and the the app both. >> >> Newt Create-Image >> >> This component needs to be modified to generate the appropriate SHA >>hashes on both the loader_app and app. >> >> Both the loader_app (optionally) and app will be built into images with >>the version presented to the create-image command. For each individual >>image, the SHA hash of the image will be appended as a TLV to the image. >> >> The a build ID hash will be generated from the hash of each image >>component. This hash will be appended to both images as aBUILD_ID_TLV. >> >> This is done to ensure that either image can be identified as being >>part of the build, and that the set of images can be identified as a >>perfect match before running them. >> >> The create image code will also be modified to create a donwload.json >>file that contains a small set of rules for downloading these image >>components to the target. For example, this may include something like: >>1. {Boot PIR: AIIC} 1. {Load SIR: { Image:loader_app.img, >>hash:23738941793274912749327497 }} 2. {Boot SIR: AIIC} 3. {Load SIR: { >>Image:bletiny.img, hash:787658576876857687568765587 }} 4. {Boot PIR: >>ADIC} >> >> This rules file defines the set of rules that the loader must use when >>loading images into this device. This will be used by newt load to >>perform the load operation. >> >> For legacy dual images, the rules will be >> >> 1. {Load SIR { Image:loader_app.img, hash:23738941793274912749327497 >>}} >> 2. {Boot SIR: AIIC} >> >> Newt Load >> >> Newt Load will be modified to read the rules file and execute the rules >>to load the target. >> >> Newt Debug >> >> This part is still unkown. TODO.. Its not clear how to get the symbols >>for both images into GDB at the same time. I suspect we will have to >>loade the symbols from the AIIC and ADIC separately. >> >> Newt Run >> >> This will just roll up the changes from the other new commands. >> >> Newt Size >> >> This must report the size of each bank image separately if there are two >> >> Mynewt Loader (AIIC implementaiton) >> >> A Loader application will be built in the apache-mynewt-core which will >>allow upgrade over serial port newtmgr and bluetooth (via the Profile >>that Vipul is writing). The loader will boot and make a first decision >>(possible after starting mynewt) whether it will run as a stand alone >>applicaiton or whether it will bypass its main routing and continue to >>boot a companion ADIC. >> >> This will be a sample which can be used by mynewt users to create their >>own loader_app or they can use this app as a stock split image loader. >> >> It will contain the following existing components >> >> 1. The bluetooth stack as a periperhal >> 2. The newtmgr bluetooth profile >> 3. Optionally the newmgr serial protocol >> 4. imgmgr Library >> 5. sysconfig >> >> The mynewt loader will have the following abilities: >> >> 1. Read the flash images and determine whether the SIR is matching or >>not via SHA. >> 2. boot into the main of the second image depending on the >>split_state in sysconfig >> 3. Handle the newtmgr commands to: inspect, program, and erase the >>SIR. >> 4. Pass image boot information to the booloader to activate and swap >>images. >> 5. Expose newtmgr interface via bluetooth and/or serial >> >> NewtMgr >> >> Newtmgr will be expanded to handle new image commands related to split >>image. >> >> Specifically >> >> 1. Ability to tell the image, that upon boot, go into AIIC or ADIC >>mode. >> >> TODO >> >> These items are still TBD >> >> 1. How to performing this magic linking. Make sure to test before >>committing to this development path. The trick is going to be to ensure >>that we don't get duplicate symbols in the ADIC >> 2. How to debug a split image. See what we can get GDB to understand >>about two images. Look up how to GDB with ROM images. Seeadd-symbol-file >>for a good start. >> >> Geek Notes >> >> this links to a geeky paper on the topic >>http://dunkels.com/adam/dunkels06runtime.pdf<http://dunkels.com/adam/dunk >>els06runtime.pdf> >> >> NOTEs From Contiki >> >> There are two aspects I'd like to share with you: >> >> 1. The only actual implementation I know of was done for 6502 based >>platforms using the cc65 toolchain. I presume that this isn't the >>platform your're interested in ;-) However for your reference here's the >>URL: >>http://contiki.cvs.sourceforge.net/viewvc/checkout/contiki/contiki-cc65/m >>ake-labels >> >> 2. The approach works in general like this: >> >> * Link the system core in the "usual" manner. >> * Get yourself a list of all public symbols and their >>corresponding addresses - obviously this only works for a >>non-relocatable binary. >> * Write some script that converts this list to an assembler >>source file that exports those symbols as aliases to their addresses in >>the system core. >> * Create an object file from the assembler source. >> * Put that object file on the linker cmdline when linking binary >>modules. >> >> This approach has two effects: >> >> 1. The Contiki APIs implemented by the system core become available >>to the modules making them work. >> 2. The C-library / compiler-runtime-library functions already present >>in the system core don't get replicated but rather reused in the modules >>making them much smaller. This is because linkers look at object files >>on the cmdline before looking into archives when resolving symbols. >> >> Notes From NUT >> >> I did this for BTnut respectively Nut/OS (I sent Rick my diploma >>theses, but not to the list as it is in German). You forgot that the >>address space needs to be adjusted, as the code must not be linked into >>memory already used by the core. Also I didn't take the detour using the >>object file, but used a customized linkerscript, which also takes care >>of the some other adjustments which have to be taken into account. >> >> For those who are not able to read Moritz' superb thesis: >> >> 1. Build the kernel and link it >> 2. Extract the symbol table from the ELF file by using objdump -t >> 3. Convert the symbol table into the form SYMBOLNAME = ADDRESS >> 4. Add this file to the linkerscript by using the option -T in gnu-ld >>and link the desired source files >> 5. You may want to write a custom LinkerScript to link the code to a >>custom address space. >> 6. Tadaaa, you have a relocated executable module > >-- >David G. Simmons >(919) 534-5099 >Web • Blog • Linkedin • Twitter • GitHub >/** Message digitally signed for security and authenticity. >* If you cannot read the PGP.sig attachment, please go to > * http://www.gnupg.com/ Secure your email!!! > * Public key available at keyserver.pgp.com >**/ >♺ This email uses 100% recycled electrons. Don't blow it by printing! > >There are only 2 hard things in computer science: Cache invalidation, >naming things, and off-by-one errors. > >
