TImada / raspi4_freertos

FreeRTOS UART sample porting to Raspberry Pi 4B.
MIT License
61 stars 22 forks source link

FreeRTOS BootELF fails #4

Open matsmithgithub opened 2 years ago

matsmithgithub commented 2 years ago

Thx for the FreeRTOS port to RPI4B!

I am able to follow your instructions and placed Ubuntu Linux 22.04 LTS 64bit diesktop on the RPI first. I used the PI imager to do this. image

I was also successful building the u-boot bin.

At first I used your instruction to copy the u-boot.bin to kernel8.img in the boot partition of the RPI imaged SD card. But, the desktop botted instead. In the config.txt file I noticed that kernel = vmlinuz file, so I changed it to kernel8.img. It then booted into u-boot image and I was able to get the u-boot prompt.

I then followed your instructions to load the uart.elf that has been copied to the SD card boot partition.

dcache off fatload mmc 0 0x28000000 uart.elf dache flush bootelf 0x28000000

After the bootelf there is no response indicating the start. I just get the u-boot prompt. I tried to use the u-boot go command at the entry point 0x20001788 and it attempts start, but fails with an rc=0 message.

Any advice or suggestions you can provide of course are appreciated.

Cheers Matt Smith

LabNelson commented 2 years ago

Hi Matt, i had the same error ( (https://github.com/TImada/raspi4_freertos/issues/1#issuecomment-1050900262). I dont know what I did in this special case, but these are my steps: In my bootscript I work with the address 0x30000000, so: fatload mmc 0:1 0x30000000 uart.elf bootelf 0x30000000

You can also check if you added the "enable_uart=1" in the config.txt file.

Maybe its worth a try

You can also check if it works with Ubuntu 20.04. This is what works for me.

Cheers Nelson

TImada commented 2 years ago

Hi Matt,

After the bootelf there is no response indicating the start. I just get the u-boot prompt.

Outputs of this FreeRTOS application do not appear on the u-boot console, but on UART2. Do you have a dedicated serial console connected to UART2 as described in this section?

matsmithgithub commented 2 years ago

Timada Yes, I do. I even observed the xmit pin (header pin 27) with an oscope and did not observe any signal changes. Just a steady high logic level. This is the sequence I used in u-boot. image You can see the u-boot version. I don't know if this is relevant, but you can see uboot is looking for uboot.env.

I don't know if this is diagnostic, but I loaded a simple bare metal program as an elf file with the u-boot. It just toggles a gpio pin. When I bootelf the pin does not toggle. But if I go at the start point it works toggling the gpio. Of course I tried this with your uart rtos example and it starts execution, but fails with rc=0 and there is no uart output. So, these may not be comparable cases. Seems I am doing something fundamentally wrong with u-boot process of which I have little experience.

Thx for your quick response and any further advice you can provide. Cheers.

Nelson When you finally got it to work, did you use an uart.elf file? You suggest that you had a separate kernel and uart image file like maybe you substituted a uart.img file for the kernel.img file and just booted into that way. thx

matsmithgithub commented 2 years ago

I have a new update. I disabled the MMU in startup, generated a uart.elf and loaded. It works, but I have to to do a go at the start point 0x20001788. So, dcache off fatload mmc 0 0x28000000 uart.elf dcache flush bootelf 0x28000000 go 0x20001788

So, I am going to do some more testing now to see if there are any limitations to this approach.

Thx for the feedback. Sometimes we just need a little encouragement. Of course, thx to you and others that have provided the freeRTOS port for the RPI4B!

TImada commented 2 years ago

Matt,

Thanks for having further investigation.

I cannot reproduce your problem on my raspi4 board when using the latest sample code. I will look into this problem next week. (Sorry, I have no time to do that this weekend)

Differences between my and your environments:

  1. My raspi4 board has 4GB DDR memory while your board has 2GB. What happens if you use another memory address like 0x30000000 (as Nelson mentioned) rather than 0x28000000 as the ELF file location in RAM?

  2. In my successful case, bootelf 0x28000000 finishes with the start address=0x28001788 and rc=0. An additional go 0x28001788 command is not required) This is an expected behavior, but seems different from your case.

  3. I used u-boot v2020.07. (you can obtain it from https://github.com/u-boot/u-boot/releases/tag/v2020.07) I'm not sure if looking for 'uboot.env' affects this problem.

In addition, using a hardware debugger helps in understanding exactly what is going in your board. (https://smartobject.gitlab.io/so3/so3_jtag_rpi4.html explains how to configure)

LabNelson commented 2 years ago

Good morning, I like the time shift between us :)

Nelson When you finally got it to work, did you use an uart.elf file? You suggest that you had a separate kernel and uart image file like maybe you substituted a uart.img file for the kernel.img file and just booted into that way. thx

Yes I used the uart.elf file generated in step 3 of the instruction. I also took the "u-boot.bin" kernel image (renamed to kernel8.img).

Differences between my and your environments:

1. My raspi4 board has 4GB DDR memory while your board has 2GB. What happens if you use another memory address like 0x30000000 (as Nelson mentioned) rather than 0x28000000 as the ELF file location in RAM?

I have the 8GB Version, but i think its worth a try.

In addition, using a hardware debugger helps in understanding exactly what is going in your board. (https://smartobject.gitlab.io/so3/so3_jtag_rpi4.html explains how to configure)

Thank you for the hint. I will check it out.

Good luck to you, Matt

matsmithgithub commented 2 years ago

Timada, 1) I did try loading the uart.elf file at 0x30000000 and I get the same behavior. I don't think it matters much because when you fatload the uart.elf it is just in temporary memory space. When you bootelf at the elf file location, it loads the executable code to the start location which in this case is 0x20001788.

2) Thx for the info on the response from your bootelf 0x28000000 u-boot command. I did not realize the response you get from bootelf 0x28000000 is the same I am getting the follow up go 0x20001788. To verify do you get?

starting application at 0x20001788 (I assume you meet 0x20001788 not 0x28001788) Application terminated rc = 0x0

I am interested if it reports "Application terminated". Whe I first saw this from my go 0x20001788 I thought the applicaiton terminated, but it worked.

3) I am using newer version of u-boot. I will give your version a try.

What I have determined at this point with my envinronment is that I can run your free RTOS uart code successfully by doing 2 things: 1) Make sure to comment out the memory management initialization in the start file. 2) Run the same u-boot commands you documented, but add a go 0x20001788 at the end.

I am also able to run another freeRTOS application using this method. They have allot of great IO drivers implemented.

Thx for the source line level debugging link! I am going to try this.

Nelson Thx for your feedback and yes it seems we are in complimentary time zones.

Can you tell me if you get the response after bootelf 0x28000000 as Timada suggests? starting application at 0x20001788 Application terminated rc = 0x0

Cheers everyone.

LabNelson commented 2 years ago

Hi Matt,

after bootelf 0x30000000 i get the response: Starting application at 0x20001788 ... Application terminated, rc = 0x0

after that i type run bootcmd so linux will boot. When I switch to the UART2 output the test program runs.

TImada commented 2 years ago

Hi Matt,

When did you see the following output? Did you see it twice both after bootelf 0x28000000 and after go 0x20001788 ? If you did not see it after bootelf 0x28000000, this means that loading the ELF sections failed in the do_bootelf fuction (https://github.com/u-boot/u-boot/blob/master/cmd/elf.c#L39).

## Starting application at 0x20001788
## Application terminated, rc = 0x0

I am interested if it reports "Application terminated". Whe I first saw this from my go 0x20001788 I thought the applicaiton terminated, but it worked.

Invocation of this sample program is done on the core#0 which is executing the u-boot prompt. In the execution of bootelf 0x28000000,

  1. the core#0 starts this program at _boot (https://github.com/TImada/raspi4_freertos/blob/master/FreeRTOS/Demo/CORTEX_A72_64-bit_Raspberrypi4/uart/src/startup.S#L6).
  2. the core#0 jumps to kick_core3 (https://github.com/TImada/raspi4_freertos/blob/master/FreeRTOS/Demo/CORTEX_A72_64-bit_Raspberrypi4/uart/src/startup.S#L52)
  3. the core#0 wakes the core#3 up by the sev instruction (https://github.com/TImada/raspi4_freertos/blob/master/FreeRTOS/Demo/CORTEX_A72_64-bit_Raspberrypi4/uart/src/startup.S#L56)
  4. the sample application terminates on the core#0, then the execution context will return to the u-boot prompt
  5. the core#3 starts at _boot, then main of the FreeRTOS sample will be invoked (https://github.com/TImada/raspi4_freertos/blob/master/FreeRTOS/Demo/CORTEX_A72_64-bit_Raspberrypi4/uart/src/startup.S#L49)

Therefore, the output ## Application terminated, rc = 0x0 means only "The core#0 kicked the core#3, then the application terminated on the core#0".

  1. Make sure to comment out the memory management initialization in the start file.
  2. Run the same u-boot commands you documented, but add a go 0x20001788 at the end.

Both of the above seem strange because this sample application with MMU-enabled can run on my raspi4 board without go 0x20001788. I guess that something wrong in memory behavior causes this problem.

I am also able to run another freeRTOS application using this method. They have allot of great IO drivers implemented.

I have never checked it! It seems a fork of this repository (plus newly implemented drivers).

TImada commented 2 years ago

I had some tests on my raspi4 board and found that the latest u-boot does not work as expected.

(in u-boot v2020.07)
U-Boot 2020.07 (Sep 29 2020 - 01:11:52 +0900)

DRAM:  3.9 GiB
RPI 4 Model B (0xc03112)
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from FAT... OK
In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@7d580000
U-Boot> dcache off
U-Boot> ext4load mmc 0:2 0x28000000 /home/imada/uart.elf
282512 bytes read in 42 ms (6.4 MiB/s)
U-Boot> dcache flush
U-Boot> bootelf 0x28000000
## Starting application at 0x20001788 ...
## Application terminated, rc = 0x0
U-Boot> 
(in the latest u-boot)
U-Boot 2022.07-rc5 (Jul 03 2022 - 13:52:34 +0900)

DRAM:  3.9 GiB
RPI 4 Model B (0xc03112)
Core:  201 devices, 15 uclasses, devicetree: board
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from FAT... OK
In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@7d580000
U-Boot> dcache off
U-Boot> ext4load mmc 0:2 0x28000000 /home/imada/uart.elf
282512 bytes read in 40 ms (6.7 MiB/s)
U-Boot> dcache flush
U-Boot> bootelf 0x28000000
U-Boot> 

You can see that the latest u-boot does not print any output just after execution of bootelf 0x28000000. This seems a silent failure in the command execution.

I'll look into related source code files in the latest u-boot.

TImada commented 2 years ago

I found that implementation change in parsing the autostart variable in u-boot affected bootelf behavior.

If we do not define autostart=yes, the bootelf command loads a target ELF file. But it does not boot the core#0 (resulting in a silent failure on the u-boot prompt).

So I tried the following boot sequence on the u-boot prompt. This sequence worked correctly for the MMU-enabled sample program on my raspi4 board.

U-Boot> setenv autostart yes
U-Boot> dcache off
U-Boot> ext4load mmc 0:2 0x28000000 /home/imada/uart.elf
282512 bytes read in 42 ms (6.4 MiB/s)
U-Boot> dcache flush
U-Boot> bootelf 0x28000000
## Starting application at 0x20001788 ...
## Application terminated, rc = 0x0
U-Boot> 

@matsmithgithub Could you try the boot sequence above on your board? (setenv autostart yes is added as the first command)

matsmithgithub commented 2 years ago

Thx! I will give this a try when I get back to my office.

felixfinal commented 1 year ago

Is here any solution? I have a same problem, and I've tried this issue I use logic analyzer see 3 char in uart2 tx "0x0D 0x0A 0x52", ascii is "\r\n", and uart2 rx form high to low at same time “\r\n” is first 3 char in democode I think there are some reasons why the program exits after being started.

U-Boot 2024.01-rc2-00107-gd5ff806cb5-dirty (Nov 20 2023 - 16:33:46 +0800)       

DRAM:  948 MiB (effective 3.9 GiB)                                              
RPI 4 Model B (0xc03115)                                                        
Core:  211 devices, 16 uclasses, devicetree: board                              
MMC:   mmcnr@7e300000: 1, mmc@7e340000: 0                                       
Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1...       
In:    serial,usbkbd                                                            
Out:   serial,vidconsole                                                        
Err:   serial,vidconsole                                                        
Net:   eth0: ethernet@7d580000                                                  
PCIe BRCM: link up, 5.0 Gbps x1 (SSC)                                           
starting USB...                                                                 
Bus xhci_pci: Register 5000420 NbrPorts 5                                       
Starting the controller                                                         
USB XHCI 1.00                                                                   
scanning bus xhci_pci for devices... 2 USB Device(s) found                      
       scanning usb for storage devices... 0 Storage Device(s) found            
Hit any key to stop autoboot:  0                                                
U-Boot> setenv autostart yes                                                    
U-Boot> dcache off                                                              
U-Boot> ext4load mmc 0:2 0x28000000 /uart.elf                                   
282392 bytes read in 38 ms (7.1 MiB/s)                                          
U-Boot> dcache flush                                                            
U-Boot> bootelf 0x28000000                                                      
## Starting application at 0x20001788 ...                                       
## Application terminated, rc = 0x0 
TImada commented 1 year ago

I cannot see any problem on your u-boot log because it has the execution result below:

## Starting application at 0x20001788 ...                                       
## Application terminated, rc = 0x0

This output is an expected execution result. Therefore, a problem you are having seems different from what was discussed in this issue.

You may have to check application behavior on the core#3 by using a hardware debug probe if you still have your problem even after checking UART2 cabling between your raspi4 board and PC.

TImada commented 1 year ago

I could not reproduce your problem on my raspi4.

I have tried u-boot with the same version applied in your environment. This UART sample successfully worked. You can check my u-boot log below.

U-Boot 2024.01-rc2-00107-gd5ff806cb5-dirty (Nov 21 2023 - 23:49:58 +0900)

DRAM:  998 MiB (effective 3.9 GiB)
RPI 4 Model B (0xc03112)
Core:  202 devices, 15 uclasses, devicetree: board
MMC:   mmcnr@7e300000: 1, emmc2@7e340000: 0
Loading Environment from FAT... OK
In:    serial,usbkbd
Out:   serial,vidconsole
Err:   serial,vidconsole
Net:   eth0: ethernet@7d580000
Hit any key to stop autoboot:  0
U-Boot> setenv autostart yes
U-Boot> dcache off
U-Boot> ext4load mmc 0:2 0x28000000 /home/imada/uart.elf
282512 bytes read in 40 ms (6.7 MiB/s)
U-Boot> dcache flush
U-Boot> bootelf 0x28000000
## Starting application at 0x20001788 ...
## Application terminated, rc = 0x0
U-Boot> 
felixfinal commented 1 year ago

Thanks for help. I am not good at u-boot startup process,now I know that there is no problem with the software starting. I use logic analyzer hardware catch UART2 date and checks the cable multiple times, so I will try hardware debug probe I'm glad I have the right tools