GithubHelp home page GithubHelp logo

pico-bootrom's People

Contributors

kilograham avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pico-bootrom's Issues

No FAT signature 55-AA in boot sector

I have issues using Elm Cham's fatfs to mount pico's uf2 disk and figure out that Boot sector doesn't include FAT signature 55-AA at offset 510. Current implementation has FAT signature at MBR which is not correct/enough
https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/virtual_disk.c#L295

ideally would be defined here
https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/virtual_disk.c#L63

static const uint8_t boot_sector[] = {
  // existing code
  [510] = 0x55,
  [511] = 0xAA
}

If you think the change make sense I could make an PR for it.

Running _connect_internal_flash from the debugger often fails

Hello,

The blackmagic debugger now handles multidrop, detects the RP Pico and implement Erase/flash via the ROM functions via the trampoline via the debugger: blackmagic-debug/blackmagic#843

As test, I use the debug build of pico-examples/blink. Flashing with BMP hosted like "blackmagic blink/blink.bin" mostly works. However often, the first call to _connect_internal_flash() fails and PC ends up as 0x100001c4, that is the hardfault handler of blink. Running with the bmp gdb server in firmware always fail, here no usb transactions happen but introducings delay did not help neither.

Any hints welcome!

Bootrom function _reset_to_usb_boot only works if XOSC is running

The bootrom function _reset_to_usb_boot (code 'U', 'B') fails to reboot to USB if the XOSC is not running.

This seems to be caused by the use of watchdog_reboot(), which switches to this oscillator without checking if it is running: https://github.com/raspberrypi/pico-bootrom/blob/master/usb_device_tiny/runtime.c#L94-L96
(called from https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/bootrom_main.c#L222)

As a workaround, before calling the bootrom function, the oscillator should be started if it's not running. (It's not necessary to switch to the XOSC oscillator.)
It may also be necessary to ensure other parts of the clock configuration are compatible with the XOSC oscillator. I didn't check that. However, the default configuration after bootup is compatible, it's only missing the XOSC startup.

Section text will not fit in ROM

I tried building the bootrom on Windows and LInux, booth builds faile with the same error (windows example):

[build] c:/progra~2/armgnu~1/112202~1.02/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld.exe: bootrom.elf section `.text' will not fit in region `ROM'
[build] c:/progra~2/armgnu~1/112202~1.02/bin/../lib/gcc/arm-none-eabi/11.2.1/../../../../arm-none-eabi/bin/ld.exe: region `ROM' overflowed by 16384 bytes
[build] collect2.exe: error: ld returned 1 exit status
[build] NMAKE : fatal error U1077: "C:\PROGRA~2\ARMGNU~1\112202~1.02\bin\AR19DD~1.EXE": R³ckgabe-Code "0x1"
[build] Stop.
[build] NMAKE : fatal error U1077: ""C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.27.29110\bin\HostX86\x86\nmake.exe"": R³ckgabe-Code "0x2"
[build] Stop.
[build] NMAKE : fatal error U1077: ""C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.27.29110\bin\HostX86\x86\nmake.exe"": R³ckgabe-Code "0x2"
[build] Stop.
[build] Build finished with exit code 2

steps to reproduce:
git clone https://github.com/raspberrypi/pico-bootrom
cd pico-bootrom
git submodule update --init
mkdir build
cd build
cmake ..
make -j4

Can not bootload with another microcontroller

Hi,

We are trying to flash the pico with an esp32s3 and a sd card.

The esp32 setup can copy the uf2 to a usb flash drive and the destination file matches the original.

When the pico is plugged in place of the flash drive, it enumerates. I can read a text file from it and copy up to 1036288 bytes worth of the uf2 to it. After this it fails with i/o error (errno=5).

The esp32 usb host stack does not trigger a single error.

Any ideas on what else I can try?

Thank you.

consider lowering bootloader current requirement to 100mA

I was working with a colleague on a guide to using an ipad text editor with CircuitPython. We ran into trouble when an RP2040 board was plugged in that was never flashed, the ipad's operating system would say that it couldn't successfully power the device. For more info: https://blog.adafruit.com/2022/05/11/new-guide-edit-circuitpython-code-on-ios-with-runestone-adafruitlearningsystem-adafruit-circuitpython-simonbs-makermelissa/

I assume (did not measure) that the device would not exceed 100mA in bootloader mode. If so, the current limit should be lowered. 100mA request may improve compatibility with un-powered hubs or with OTG devices like an ipad.

Note that we haven't been able to successfully uf2-flash a device from an ipad, but not getting the scary power warning would be nice.

watchdog_reboot into flash should set some scratch fields

When we reboot into RAM we indicate this via

watchdog_hw->scratch[4] = 0xb007c0d3;
watchdog_hw->scratch[5] = pc ^ -0xb007c0d3;
watchdog_hw->scratch[6] = sp;
watchdog_hw->scratch[7] = pc;

however on rebooting into flash we only reset scratch[4] to 0 (which is also done on the watchdog boot path in the bootrom).

It would be nice to be able to detect a bootrom reset vs another type of watchdog reset explicitly.

is_address_rom only returns true for the first 8191 bytes

is_address_rom only returns true for addresses between 0 and 8191 inclusive, however we ROM area is 16 KiB. This causes reads to the bootrom area (with READ commands from the PICOBOOT interface) to fail if we try to read anything in the 8191 to 16384 range. Note that it is not possible to read address 8191 since the READ command checks for is_address_rom(address + size).

The function should check <= 16384 instead of < 8192.

A possible workaround is to use EXEC commands to copy the ROM area to RAM and then READ from RAM.

Just FYI if somebody runs into this problem.

Recognize "standard" run-from-ram binaries from bootloader?

I realize that this would mean a ROM change, and I'm not sure how important it is, but...

As I understand it, if you load a UF2 file that contains only RAM content, the bootloader will assume that it is a run-from-ram binary and start it at the lowest address that has been loaded:

static void _write_uf2_page_complete(struct async_task *task) {

       if (!task->result && _uf2_info.valid_block_count == _uf2_info.num_blocks) {
            safe_reboot(_uf2_info.ram ? _uf2_info.lowest_addr : 0, SRAM_END, 1000); //300); // reboot in 300 ms
        }

This is ok, but is incompatible with "standard" cortex binaries that have the "initial stack pointer" in the vector table at their lowest location.
I think it would only require a little bit of code for either the WD reset code, or the bootrom that sets it up, to notice that the first lword in the binary looks more like a Initial SP value than code, and take appropriate action to support bother traditional cortex binaries as well as the Pico-SDK style RAM binaries.

SCSI inquiry length is 37, should be 36

With the RP2040 in bootloader mode, one gets:

$ sg_inq --only /dev/sdb
standard INQUIRY:
  PQual=0  PDT=0  RMB=1  LU_CONG=0  hot_pluggable=0  version=0x02  [SCSI-2]
  [AERC=0]  [TrmTsk=0]  NormACA=0  HiSUP=0  Resp_data_format=2
  SCCS=0  ACC=0  TPGS=0  3PC=0  Protect=0  [BQue=0]
  EncServ=0  MultiP=0  [MChngr=0]  [ACKREQQ=0]  Addr16=0
  [RelAdr=0]  WBus16=0  Sync=0  [Linked=0]  [TranDis=0]  CmdQue=0
    length=37 (0x25), but only fetched 36 bytes   Peripheral device type: disk
 Vendor identification: RPI     
 Product identification: RP2             
 Product revision level: 2   

Note that the length=37 but it should be 36.

The issue is this line: https://github.com/raspberrypi/pico-bootrom/blob/master/usb_device_tiny/scsi_ir.h#L32
The - 4 should be a - 5.

Originally discussed here: hathach/tinyusb#1349

uf2 flash partially if not start at 4K boundary

Trying to do this:

dd if=/dev/urandom of=random.bin bs=1024 count=100
uf2conv.py -b 0x10020100 -o random.uf2 -c -f RP2040 random.bin
cp random.uf2 /mnt/uf2 && sync

Note that address starts at 0x10020100: after reboot, content between 0x****000 and 0x***100 stays unchanged (0xFFFFFFFF), shown as following:
( see https://gist.github.com/juju2013/6e5d129effd3e7d3b43a6bc8973306ff )
$10020100 ........ $10021000 FFFFFFFF $10021100 ........ $10022000 FFFFFFFF $10022100 ........ $10023000 FFFFFFFF $10023100 ........ $10024000 FFFFFFFF $10024100 ........ $10025000 FFFFFFFF $10025100 ........ $10026000 FFFFFFFF $10026100 ........ $10027000 FFFFFFFF $10027100 ........ $10028000 FFFFFFFF $10028100 ........ $10029000 FFFFFFFF $10029100 ........ $1002A000 FFFFFFFF
If that address starts at a 4K boundary, content flashed as expected.

Documentation says ( 2.8.3.2. UF2 Format Details ):
Note that flash is erased a 4K sector at a time, so writing to only a subset of a 4K flash sector will leave the rest of that flash sector undefined. Beyond that there is no requirement that a binary be contiguous.

Release ELF?

The sources are a great resource. Perhaps the project could also publish binaries under "Release". The ELF corresponding to the mask ROM binary would be most useful for various purposes, not least of which is comparing against independent builds from source.

Feature requests for next mask ROM rev

Hi,

I fully understand that this will not happen quickly due to the cost and complexity of revving your mask ROM. But if you do get around to it I would ask that you consider the following:

As early as possible, ideally before pushing anything onto the stack, make a basic memory test (set 1's, verify, set 0's, verify) on the last 1K block of SRAM (enough to cover 2nd stage bootloader and stack below it). If any memory test fails then move to the next 1K block, and so on. Only set the stack pointer after checking that the SRAM is ready to go. It would ensure that first stage stack and the second stage stack are not corrupted.

Thanks for listening,

Jonathan

flash_read_data in v1 mask ROM

void __noinline flash_read_data(uint32_t addr, uint8_t *rx, size_t count) {
    assert(addr < 0x1000000);
    flash_put_cmd_addr(FLASHCMD_READ_DATA, addr);
    flash_put_get(NULL, rx, count, 4);
}

Here is the disassembly of what appears in the v1 mask ROM:

flash_read_data:
    17e0:	b510      	push	{r4, lr}
    17e2:	000c      	movs	r4, r1
    17e4:	0001      	movs	r1, r0
    17e6:	2003      	movs	r0, #3
    17e8:	f7ff f9da 	bl	0xba0 ; flash_put_cmd_addr
    17ec:	2280      	movs	r2, #128	; 0x80
    17ee:	2304      	movs	r3, #4
    17f0:	0021      	movs	r1, r4
    17f2:	2000      	movs	r0, #0
    17f4:	0052      	lsls	r2, r2, #1
    17f6:	f7ff ffbf 	bl	0x1778 ; flash_put_get
    17fa:	bd10      	pop	{r4, pc}

One will notice that upon entry: r0=addr, r1=rx, and r2=count. r4 is used as a temporary. Argument shuffling is done prior to the call of flash_put_cmd_addr( ), which proceeds as expected. However, notice what happens to the arguments for flash_put_get( ). r0=0 (NULL), r1=rx (previously saved in r4), r3=4. But r2=0x80<<1=256!

The build appears to have optimized flash_read_data( ) to perform only count=256.

This is not an outright bug. But it certainly makes flash_read_data( ) not work as advertised, should it ever be called from outside the mask ROM (which is exactly what I had wished to do in a custom 2nd stage bootloader).

Enhancement: Bootstrap Voltage Select

From section 2.19.4 of datasheet:

Both the output signal level and acceptable input signal level at the pad are determined by the digital IO supply (IOVDD).
IOVDD can be any nominal voltage between 1.8V and 3.3V, but to meet specification when powered at 1.8V, the pad
input thresholds must be adjusted by writing a 1 to the pad VOLTAGE_SELECT registers. By default the pad input thresholds
are valid for an IOVDD voltage between 2.5V and 3.3V. Using a voltage of 1.8V with the default input thresholds is a safe
operating mode, though it will result in input thresholds that don’t meet specification.

Context:
https://forums.raspberrypi.com/viewtopic.php?t=328887

Would be nice to use a GPIO during bootloader to set this. A simple pull-down vs pull-up should not compromise the pin's operation. Not critical but would be nice on next version of RP2040, whenever that may be. Should be possible to ensure backwards compatibility.

Note this may be considered pointless in most applications. This could be fixed few ways if this becomes problematic, however these work arounds could increase cost.

source code doesn't match mask ROM?

I have been unable to re-create an image that matches the RP2040 mask ROM, at least on the parts that I have. There are non-trivial differences.

Having an .elf file to trace through Boot ROM code execution is rather important in diagnosing RP2040 behavior.

I’m using this to compile (which ostensibly matches what the README says):

gcc version 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] (GNU Tools for Arm Embedded Processors 9-2019-q4-major)

The 8 most significant hex digits of the Bootrom git revision are: 0xd24340e4

The bootrom version byte at 0x13 is 0x01

How any of this relates to the “B1” specified in the README is not clear.

The README also speaks of “built in debug mode”. I’ve tried both:

cmake -DCMAKE_BUILD_TYPE=Debug .
cmake .

without any change in the output file.

I've attached a binary of what the mask ROM is on the parts that I have.

rp2040maskrom.zip

Thanks.

Discontiguous UF2 files not written consistently

Hi! I am admittedly doing something slightly odd, but that odd thing may have exposed a bug in the firmware loading code.

The build system for Hubris lays out separately compiled tasks in isolated memory containers. This means that its Flash footprint consists of a series of (power-of-two-aligned) chunks, many of which are not full. For instance,

ADDRESS  END          SIZE FILE
10000100 100001a8       a8 target/demo-pi-pico/dist/kernel
100001a8 10002b20     2978 target/demo-pi-pico/dist/kernel
10002b20 10002db8      298 target/demo-pi-pico/dist/kernel
10003000 10003048       48 target/demo-pi-pico/dist/idle
10003400 10003708      308 target/demo-pi-pico/dist/sys
10003708 10003710        8 target/demo-pi-pico/dist/sys
10003800 10003aec      2ec target/demo-pi-pico/dist/user_leds
10003aec 10003b48       5c target/demo-pi-pico/dist/user_leds

For instance, in the example layout above, there's a gap between the end of the kernel text (at ...2db8, or ...2e00 when rounded up to the next Flash sector) and the beginning of the next program's text at ...3000.

I've altered our build system to produce UF2 and I've tested it in two different modes. In "contiguous" mode, it generates zero-filled records for gaps like the one described above. In "discontiguous" mode, it does not (and the block count and whatnot is reduced accordingly). The datasheet didn't talk me out of doing discontiguous UF2s; indeed, section 2.8.4.2 mentions offhand that

Note that flash is erased a 4K sector at a time, so writing to only a subset of a 4K flash sector will leave the rest of that
flash sector undefined. Beyond that there is no requirement that a binary be contiguous.

I went and studied virtual_disk.c and associated code, and it looks like it's trying to do the right thing even if blocks are discontiguous, out of order, etc. So, it sure looks like this should work!

However, when loading in discontiguous mode, the Flash is not being written correctly. Specifically, the Flash will be written up to the final sector in a contiguous region, and then the first few sectors of the region after the gap are erased but not written, so they read back as FF FF etc. Example (from a conversation through gdb+openocd):

(gdb) mon mdb 0x10002d00 16
0x10002d00: 05 00 00 00 00 00 00 00 00 07 00 20 00 01 00 00 

(gdb) mon mdb 0x10002e00 16  # expected to be FFs, this is the gap
0x10002e00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 

(gdb) mon mdb 0x10003000 16  # expected to have a program in it!
0x10003000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

The UF2 record that should have been written there reads:

00005c00  55 46 32 0a 57 51 5d 9e  00 20 00 00 00 30 00 10  |UF2.WQ].. ...0..|
00005c10  00 01 00 00 2e 00 00 00  68 00 00 00 56 ff 8b e4  |........h...V...|
00005c20  0a 48 0b 49 0b 4a 01 e0  08 c9 08 c2 82 42 fb d1  |.H.I.J.......B..|
00005c30  09 48 0a 49 00 22 00 e0  04 c1 81 42 fc d1 bf f3  |.H.I.".....B....|
00005c40  4f 8f bf f3 6f 8f 00 f0  0b f8 fe de 00 07 00 20  |O...o.......... |
00005c50  48 30 00 10 00 07 00 20  00 07 00 20 00 07 00 20  |H0..... ... ... |
00005c60  80 b5 00 af 30 bf fd e7  00 00 00 00 00 00 00 00  |....0...........|
00005c70  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00005df0  00 00 00 00 00 00 00 00  00 00 00 00 30 6f b1 0a  |............0o..|

The problem extends up until address ...3500 at which point sectors start being written correctly again. (This is a curious point for things to change, as it's not an erase sector boundary.)

So, I am either missing something, or there's a subtle bug here.

I have attached gzip'd UF2 images of the firmware (compiled for Pi Pico) in both contiguous mode (works!) and discontiguous mode (fails as described above). If you try it, the "working" case should blink the LED at about 1 Hz, while the failure case will set the LED and then hard fault when it jumps into an erased flash sector.

contiguous.uf2.gz
discontiguous.uf2.gz

Character constants without right apostrophe

Some of the following character constants don't have a right apostrophe, e.g. 'F instead of 'F':

.byte 'F, 'S'
.hword mufp_lib_start
.byte 'F, 'E'
.hword mufp_lib_end
// expose library start and end to facilitate users copying into RAM
.byte 'D, 'S'
.hword mufp_lib_double_start
.byte 'D, 'E'
.hword mufp_lib_double_end
.hword 0

For some reason this nevertheless assembles correctly?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.