When using serial as upload_protocol the main.py script used for flashing uses wrong parameter for specifying flashing start address. It actually uses -g parameter, but this parameter is used for execution start, not flashing start. The parameter that should be used is -S.
This bug prevents flashing to addresses different from default flashing address (0x8000000). This parameter is used for example to create a bootloader and main firmware stored in different memory addresses.
This is an old and annoying bug that I fix myself locally each time I update stm32 platform for plaformio.
I use st stm32 platform v15.3.0
OS: mac OS Big Sur
How to fix the issue:
change the parameter -g to -S in .platformio/platforms/ststm32/builder/main.py:278