[U-Boot-Users] intended behavior of bootm
Jerry Van Baren
gerald.vanbaren at ge.com
Mon Apr 21 18:28:44 CEST 2008
Matthias Fuchs wrote:
> Hi Jerry,
>
> On Monday 21 April 2008 17:16, Jerry Van Baren wrote:
>> Matthias Fuchs wrote:
>>> Hi,
>>>
>>> after going through the boom code I found out, that
>>> setting the 'autostart' variable to 'no' brings me a little closer
>>> to what I want. But finally I end up
>>> in the enable_interrupts() at the very end of do_bootm(). This freezes
>>> my system. The reason for this is the Linux kernel image that is loaded to address 0
>>> and that overwrites the vector table. So reenabling the interrupts in U-Boot with
>>> Linux interrupt table is a bad idea.
>> No, having your (u-boot) interrupt go off while booting linux is a bad idea.
> U-Boot calls disable_interrupt() in do_bootm(). That's fact.
>
>> Which interrupt is going off? Why is it going off (why isn't the
>> hardware put into a quiescent state)?
>>
>>> So what's the best idea to fix this? I could copy the vector table onto the stack
>>> in do_bootm() and copy it back just before reenabling the interrupts.
>> NO NO NO.
> At least this works :-)
At least once. Today. :-/
>>> Any better idea?
>>>
>>> Matthias
>> That a u-boot initialized interrupt is occurring is wrong and needs to
>> be fixed.
>> * Traditionally, u-boot does not use interrupts for anything, thus this
>> isn't a problem.
>>
>> * Proper hardware and device driver convention is that the hardware must
>> be quiescent when linux is started and the linux device driver must
>> (re)configure that hardware the way it wants/needs. Obviously, this is
>> probably a 95% rule (console I/O, memory initialization, some others may
>> violate this rule for practical reasons).
>>
>> * If your u-boot enables interrupt(s), you MUST disable the interrupt
>> source before starting linux. There is NO graceful way of getting linux
>> to handle an interrupt that was a result of u-boot's running. Starting
>> linux with interrupts disabled is not a good solution - you may get
>> lucky but leaving an active interrupt source is a dangerous game. At
>> best, it is a race condition that you may happen to win today.
> So this means that U-Boot calling disable_interrupts before booting Linux (see do_bootm)
> is correct. Later my the kernel images is loaded at address 0. This overwrites all U-Boot vectors
> in the first 16k of RAM. So when after the kernel is loaded to address 0 and the ramdisk
> CRC checking failed to control is to be passed back to U-Boot it sees a mixed up vector table.
> I think the only ways to fix this is to save the table (as I did for testing)
That is the way of INsanity.
> or check the ramdisk images before uncompressing the kernel at address 0.
That is the way of sanity.
I missed a piece of the puzzle... the problem isn't an interrupt going
off in linux-land, the problem is that linux failed to run (CRC error -
implies a bad load) and you are trying to recover without resetting the
system.
That isn't reliable. It is possible that it could be done, but I
wouldn't bet on it being reliable, at least not long term. I would
anticipate that to be a very fragile solution - eventually the linux
kernel will do *something* different/unexpected before aborting and your
recovery mechanism will blow up.
Our current solution revolves around verifying the boot image and
aborting the launch *before* attempting to launch it, before it becomes
impossible to recover.
In bootm, you will see that there is a "point of no return"
corresponding to replacing the interrupt vectors. After the "point of
no return" we don't attempt to return from the failed bootm, but rather
reset the hardware to recover. You are trying to go *way beyond* the
"point of no return" (all the way to some indeterminate point in the
linux boot process) and still trying to recover without a reset. Ouch.
You don't know (in general) *what* the linux initialization did (it is
busy scribbling on memory, if nothing else), so it is impossible to
guarantee that what it did is reversible.
> Except from that I just noticed that 'autostart=no' does not help me, because it completely disables booting
> the kernel from bootm.
>
> So how can I achive this:
>
> bootm $(kernel_addr_in_flash) $(randisk_addr_in_flash); run load_images_from_usb_to_ram; bootm $(kernel_addr_in_ram) $(ramdisk_addr_in_ram)
>
> So the the initial bootm fails because of invalid images, U-Boot
> should load images from a USB media and start them.
The current u-boot has ways to detect invalid images before leaping.
The way of sanity is to identify invalid images before leaping, and
filling in holes in our detection, as necessary. The new boot image
format may also be helpful here.
> Matthias
Best regards,
gvb
More information about the U-Boot
mailing list