Modifying ncs 2.3.0 to work with a custom bootloader - need help `weakening` some symbols...

I am using the `mcumgr` subsys to enable the DFU (Device Firmware Update) capabilities in a custom device that also features a custom (non mcuboot) bootloader. In order to get the so called Image Management Group SMP commands to work properly, we need to override the following functions (defined in the various source files).

(which we have done right now by *explcitly* weakening them in the source code)

Here is one example

`subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c`

int __attribute__((weak))
img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash,
                   uint32_t *flags)

We are then able to make the inbuilt mcumgr layer interact with our *custom* implementation and all is good.

I wanted to know if there was a *better* way to do this (i.e. one that does not require any source code modifications on the NSC source tree).

An AI enabled 'vibe coding' IDE that I have been using recently suggested using the `-Wl, --wrap=img_mgmt_read_info` trick, but this did not seem to work.

Thanks in advance.

Regards,

Sidd

Parents
  • Hello Sidd,

    I haven't used this linker option before, but it seems like a very neat feature. I'm not aware of any better way to achieve the same without making changes to the SDK tree. I tried it with the smp_srv sample in Zephyr (nRF Connect SDK v3.0.2), and it appears to work as expected. 

    First I defined the wrapper function in main.c

    extern int __real_img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash,
    				   uint32_t *flags);
    
    int __wrap_img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash, uint32_t *flags)
    {
    	LOG_ERR("wrapper function called");
    	return __real_img_mgmt_read_info(image_slot, ver, hash, flags);
    }
     

    then I added the linker options to the project's cmakelist file:

    project(smp_svr)
    target_link_options(app PUBLIC -Wl,--wrap=img_mgmt_read_info) 
    target_sources(app PRIVATE src/main.c)

    Log output after reading the image slots from the phone shows that my wrapper function was invoked:

    It might be worth adding that this option did not work for me when I tried enabling link time optimization (LTO). I figured I would to test this after I read the comment here link suggesting that you can't wrap functions defined and used in the same compilation unit. NCS v2.3.0 does not support LTO, so it is not relevant right now, but could be in the future.

    Best regards,

    Vidar

Reply
  • Hello Sidd,

    I haven't used this linker option before, but it seems like a very neat feature. I'm not aware of any better way to achieve the same without making changes to the SDK tree. I tried it with the smp_srv sample in Zephyr (nRF Connect SDK v3.0.2), and it appears to work as expected. 

    First I defined the wrapper function in main.c

    extern int __real_img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash,
    				   uint32_t *flags);
    
    int __wrap_img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash, uint32_t *flags)
    {
    	LOG_ERR("wrapper function called");
    	return __real_img_mgmt_read_info(image_slot, ver, hash, flags);
    }
     

    then I added the linker options to the project's cmakelist file:

    project(smp_svr)
    target_link_options(app PUBLIC -Wl,--wrap=img_mgmt_read_info) 
    target_sources(app PRIVATE src/main.c)

    Log output after reading the image slots from the phone shows that my wrapper function was invoked:

    It might be worth adding that this option did not work for me when I tried enabling link time optimization (LTO). I figured I would to test this after I read the comment here link suggesting that you can't wrap functions defined and used in the same compilation unit. NCS v2.3.0 does not support LTO, so it is not relevant right now, but could be in the future.

    Best regards,

    Vidar

Children
No Data
Related