U-Boot application causes reset - fpga

This question might be too broad and may not be easily understandable until you see actual code or what is happening, but I thought I should give at least a try. I am porting U-boot for RISCV cpu on MAX10 FPGA in its DDR3 Memory. I have made all the necessary configurations for my specific board and processor as mentioned in the README of U-boot and it is successfully built as well.
But, currently I am unable to get into U-boot application for some reason. Whenever I prompt it to enter into address that I have specified in CONFIG_SYS_LOAD_ADDR which is 0x80000000, it resets and starts from address 0x00000000. I don't have any idea that why is this happening. Can someone expert with this stuff help me?

Whenever I prompt it to enter into address that I have specified in CONFIG_SYS_LOAD_ADDR which is 0x80000000, it resets and starts from address 0x00000000.
CONFIG_SYS_LOAD_ADDR is merely a default load address for various U-Boot commands (e.g. tftpboot).
The symbol that does need to be defined is CONFIG_STANDALONE_LOAD_ADDR, which is used as the linker address for standalone applications.
The U-Boot standalone applications are built as non-relocatable code.
Since your application was built with an unknown default link address, it is unlikely to properly execute at 0x80000000.
If you haven't already, you should also perform a memory test using U-Boot's memtest.

Related

Multiple Boot loaders in same PIC32MZ?

Heading seems kinda weird, I am also not getting what exact should I write there, but hope I am able to make you understand what I want to do exactly!
- I will have Primary bootloader and secondary bootloader both will resides in different areas of memory (may be boot flash or program flash).
- One of bootloader will be active at a time and other will be inactive.
- Let consider, Primary bootloader is active, and now I will download my application firmware. I am also reading the active bootloader version from application firmware so that I can check whether I need to update bootloader.
- And If I need to update bootloader then inactive bootloader will be activated and it will replace previously active bootloader with updated one. And secondary bootloader will switch back to inactive mode. Thus secondary bootloader only become active when it have to update primary bootloader.
- In whole this process, I want to reserve some memory area for Primary bootloader version, secondary bootloader version, and some custom configuration data with fixed memory location and can be accessible from Primary, secondary as well as application firmware.
You'll need to understand the Linker files. I have yet to do this for the MX/MZ line but I have don this sort of thing on MANY dsPIC33's. Pretty much the following way: Bootloader gets a set amount of flash dedicated in the .gld usually a single page so it's easier to erase (0x400) then the Superboot loader (the secondary bootloader) is ONLY loaded into the PIC when you are actually loading a new bootloader. So what the superboot loader is is really a smaller application designed to simply update the bootloader and then jump to the reset address of the bootloader. I personally wouldn't keep the secondary/super bootload code in there all the time simply to avoid confusion later on. You can really do this using update techniques from outside the PIC. Again I can;t offer direct help with the PIC32 line but if you'd like to see example linker files for the dsPIC33 lines I can provide those.

Change vm page protection attributes from XNU kernel driver

As a part of an experiment i need to make a read-only page writable in kernel address space from a non-IOKit kext. In user mode i can do vm_protect, but there is surprisingly little info on how this can be done in kernel mode (or i am completely blind). Is there a call to do this?
In the kernel, it's declared in <mach/vm_map.h>, and is part of the "unsupported" KPI. (Add com.apple.kpi.unsupported to OSBundleRequired of your kext's info.plist) I unfortunately haven't used this function from the kernel before, so I can't really comment beyond that. vm_map_t appears to be a Mach Port reference, but I'm not sure where you'd get it from.

Boot U-boot from RAM using U-boot

I would like to boot an U-boot image from RAM using another U-boot. I loaded the U-boot image in the RAM using tftp tftp 0x90000000 u-boot.img and tried to run it with go 0x90000000 but nothing happens. I guess there are some conflicts concerning the initializations. When I went to the U-boot code, I found in the file /arch/arm/cpu/armv7/start.S the following comment do important init only if we don't start from memory!. So I have some questions.
First of all, is it possible to do that?
Any Idea of what are those important init?
And is there anything else I need to remove from the u-boot code?
I spent a couple of days trying to do the same thing in order to avoid the hassle of burning each new image version to flash, after all, if I have a working bootloader why not load a new version from it. I think this section of U-Boot documentation page explains perfectly why this not impossible.
If you want to start U-Boot from another boot loader, you must disable a lot of code, i. e. all initialization parts that already have been performed by this other boot loader...
The code you have to disable contains the most critical parts in U-Boot, i. e. these are the areas where 99% or more of all errors are located when you port U-Boot to a new hardware. In the result, your RAM image may work, but in the end you will need a full image to program the flash memory with it, and then you will have to enable all this highly critical and completely untested code.

how to debug a pci device and linux driver

I am programming a pci device with verilog and also writing its driver,
I have probably inserted some bug in the hardware design and when i load the driver with insmod the kernel just gets stuck and doesnt respond. Now Im trying to figure out what's the last driver code line that makes my computer stuck. I have inserted printk in all relevant functions like probe and init but non of them get printed.
What other code is running when i use insmod before it gets to my init function? (I guess the kernel gets stuck over there)
printks are often not useful debugging such a problem. They are buffered sufficiently that you won't see them in time if the system hangs shortly after printk is called.
It is far more productive to selectively comment out sections of your driver and by process of elimination determine which line is the (first) problem.
Begin by commenting out the entire module's init section leaving only return 0;. Build it and load it. Does it hang? Reboot system, reenable the next few lines (class_create()?) and repeat.
From what you are telling, it is looks like that Linux scheduler is deadlocking by your driver. That's mean that interrupts from the system timer doesn't arrive or have a chance to be handled by kernel. There are two possible reasons:
You hang somewhere in your driver interrupt handler (handler starts its work but never finish it).
Your device creates interrupts storm (Device generates interrupts too frequently as a result your system do the only job -- handling of your device interrupts).
You explicitly disable all interrupts in your driver but doesn't reenable them.
In all other cases system will either crash, either oops or panic with all appropriate outputs or tolerate potential misbehavior of your device.
I guess that printk won't work for such extreme scenario as hang in kernel mode. It is quite heavy weight and due to this unreliable diagnostic tool for scenarios like your.
This trick works only in simpler environments like bootloaders or more simple kernels where system runs in default low-end video mode and there is no need to sync access to the video memory. In such systems tracing via debugging output to the display via direct writing to the video memory can be great and in many times the only tool that can be used for debugging purposes. Linux is not the case.
What techniques can be recommended from the software debugging point of view:
Try to review you driver code devoting special attention to interrupt handler and places where you disable/enable interrupts for synchronization.
Commenting out of all driver logic with gradual uncommenting can help a lot with localization of the issue.
You can try to use remote kernel debugging of your driver. I advice to try to use virtual machine for that purposes, but I'm not aware about do they allow to pass the PCI device in the virtual machine.
You can try the trick with in-memory tracing. The idea is to preallocate the memory chunk with well known virtual and physical addresses and zeroes it. Then modify your driver to write the trace data in this chunk using its virtual address. (For example, assign an unique integer value to each event that you want to trace and write '1' into the appropriate index of bytes array in the preallocated memory cell). Then when your system will hang you can simply force full memory dump generation and then analyze the memory layout packed in the dump using physical address of the memory chunk with traces. I had used this technique with VmWare Workstation VM on Windows. When the system had hanged I just pause a VM instance and looked to the appropriate .vmem file that contains raw memory latout of the physical memory of the VM instance. Not sure that this trick will work easy or even will work at all on Linux, but I would try it.
Finally, you can try to trace the messages on the PCI bus, but I'm not an expert in this field and not sure do it can help in your case or not.
In general kernel debugging is a quite tricky task, where a lot of tricks in use and all they works only for a specific set of cases. :(
I would put a logic analyzer on the bus lines (on FPGA you could use chipscope or similar). You'll then be able to tell which access is in cause (and fix the hardware). It will be useful anyway in order to debug or analyze future issues.
Another way would be to use the kernel crash dump utility which saved me some headaches in the past. But depending your Linux distribution requires installing (available by default in RH). See http://people.redhat.com/anderson/crash_whitepaper/
There isn't really anything that is run before your init. Bus enumeration is done at boot, if that goes by without a hitch the earliest cause for freezing should be something in your driver init AFAIK.
You should be able to see printks as they are printed, they aren't buffered and should not get lost. That's applicable only in situations where you can directly see kernel output, such as on the text console or over a serial line. If there is some other application in the way, like displaying the kernel logs in a terminal in X11 or over ssh, it may not have a chance to read and display the logs before the computer freezes.
If for some other reasons the printks still do not work for you, you can instead have your init function return early. Just test and move the return to later in the init until you find the point where it crashes.
It's hard to say what is causing your freezes, but interrupts is one of those things I would look at first. Make sure the device really doesn't signal interrupts until the driver enables them (that includes clearing interrupt enables on system reset) and enable them in the driver only after all handlers are registered (also, clear interrupt status before enabling interrupts).
Second thing to look at would be bus master transfers, same thing applies: Make sure the device doesn't do anything until it's asked to and let the driver make sure that no busmaster transfers are active before enabling busmastering at the device level.
The fact that the kernel gets stuck as soon as you install your driver module makes me wonder if any other driver (built in to kernel?) is already driving the device. I made this mistake once which is why i am asking. I'd look for the string "kernel driver in use" in the output of 'lspci' before installing the module. In any case, your printk's should be visible in dmesg output.
in addition to Claudio's suggestion, couple more debug ideas:
1. try kgdb (https://www.kernel.org/doc/htmldocs/kgdb/EnableKGDB.html)
2. use JTAG interfaces to connect to debug tools (these i think vary between devices, vendors so you'll have to figure out which debug tools you need to the particular hardware)

Determining why kernel hangs on boot

hi :
i was building kernel for my gentoo linux . when i start the kernel , i
got this message , and can't going on.
pci_hotplug: PCI Hot Plug PCI Core version: 0.5
non-volatile memory driver v1.3
i don't know how to solve this problem . and i need help . thanks .
Why don't you try to disable pci hotplug support in kernel (if I recall correctly is in main config menu / PCI support)? You probably don't need this.
I'm going to have to disagree with those voting to close, because I think there really is a question here, and the question is "How to debug this?"
I'm going to propose two approaches:
1) Studious approach: Learn about mechanisms intended for handling boot problems. See if you can increase the kernel debug message level. Disable un-needed drivers as Quizzo suggested.
2) Cowboy approach: grep the kernel sources for strings seen in the final messages, and start shotgunning all possibly relevant bits of code with your own "still alive at" printk messages. Once you know where it's hanging, figure out why and either remove that mechanism or fix it.
At an extreme there's also a tool for debugging the kernel - kgdb - which you could set up if you have a second machine available.
If you already have linux running on this box, see if there's a config.gz in /proc or in a boot folder which you can extract and compare to the configuration you are trying to compile. It might not be a bad idea to first recompile and test exactly the same version and configuration as you have running, and then make desired changes one by one.
Also you might see if there's odd hardware in your system you could temporarily remove. For example, an older PC I have has a bios that hangs during drive enumeration if I have a large USB external drive plugged in during boot.
i have solved the problem by enable all pci hotplug flag in kernel config file.
thinks all.

Resources