I am booting the kernel (arm, cortexa15), and the kernel hung at:
## Booting kernel from Legacy Image at 40007fc0 ...
Image Name: Linux-4.4.138-cip25-rt19-yocto-s
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5510400 Bytes = 5.3 MiB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 40f00000
Booting using the fdt blob at 0x40f00000
XIP Kernel Image ... OK
Loading Device Tree to 40ef1000, end 40effb37 ... OK
Starting kernel ...
I tried to enable earlyprintk to know where the kernel stuck.
CONF_PRINTK=y
CONF_EARLY_PRINTK=y
CONFIG_DEBUG_LL=y (low-level debug)
# CONFIG_DEBUG_ICEDCC is not set
and set bootargs:
> setenv bootargs ${bootargs_base} earlyprintk
But, there is not message printed on console. Anyone can help ?
I compiled a linux kernel for my Toshiba AC100 and want to boot it via uboot.
Problem: After displaying the message "Starting Kernel" nothing happens.
The flag CONFIG_DEBUG_LL was set but there is still no output after this message.
I have another precompiled kernel (but too old to use) which comes with its own dtb file and this one boots (same bootargs as the non-booting kernel).
Observation: If I change the dbt file for this kernel it shows the same behavior as the non-booting kernel, just displaying the "Starting kernel" line.
So I guess my problem is related to the dbt file I use for my kernel.
Are there any methods to check if the dbt file is right for my board?
What else could I do to get some information what the problem is?
The entry in the boot.scr:
setenv bootargs 'root=/dev/mmcblk0p7 rootfstype=ext4 earlyprintk=vga console=tty0 mem=448M#0'
setenv bootmenu_4 "Boot Arch Linux =ext2load mmc 0:7 0x1000000 /boot/zImage; ext2load mmc 0:7 0x2000000 /boot/tegra20-paz00.dtb; bootz 0x1000000 - 0x2000000"
And here's the output form u-boot:
2255488 bytes read in 116 ms (18.5 MiB/s)
14153 bytes read in 82 ms (168 KiB/s)
Kernel image # 0x1000000 [ 0x000000 - 0x226a80 ]
## Flattened Device Tree blob at 02000000
Booting using the fdt blob at 0x2000000
Loading Device Tree to 0fff9000, end 0ffff748 ... OK
Starting kernel ...
I tried also to extract the config from the working kernel and built a new kernel with this config, but this one does not work, too (does not matter which dtb file I use).
EDIT:
Finally I solved it by changing the kernel config from
CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
to
CONFIG_TEGRA_DEBUG_UARTA
After this, the kernel boots fine.
I have problem booting Linux 3.16.1. I have compiled sources from http://www.kernel.org with at91sam9263_defconfig.
I have added Flattened Device Tree support in Boot options.
Followin tips suggested in this (https://www.slideshare.net/softpapa/device-tree-support-on-arm-linux-8930303) presentation to turn on Support device tree in /proc but i don't have that option in menuconfig.
I have U-Boot bootloader version 2014.10rc2 which supports device tree.
I have generated dtb from script shipped with kernel:
make at91sam9263ek.dtb
And now i'm getting this error:
Welcome to minicom 2.5
OPTIONS: I18n
Compiled on Feb 9 2011, 14:45:00.
Port /dev/ttyS0
Press CTRL-A Z for help on special keys
RomBOOT
>
U-Boot 2014.10-rc2-00200-g9170818-dirty (Sep 23 2014 - 15:16:39)
CPU: AT91SAM9263
Crystal frequency: 16.368 MHz
CPU clock : 199.919 MHz
Master clock : 99.960 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
NAND: 256 MiB
MMC: mci: 0
In: serial
Out: serial
Err: serial
Net: macb0
Warning: Your board does not use generic board. Please read
doc/README.generic-board and take action. Boards not
upgraded by the late 2014 may break or be removed.
Hit any key to stop autoboot: 0
U-Boot> tftp uImage
macb0: Starting autonegotiation...
macb0: Autonegotiation complete
macb0: link up, 100Mbps full-duplex (lpa: 0xcde1)
Using macb0 device
TFTP from server 192.168.1.247; our IP address is 192.168.1.240
Filename 'uImage'.
Load address: 0x22000000
Loading: #################################################################
#################################################################
#################################################################
##############
1.2 MiB/s
done
Bytes transferred = 3068016 (2ed070 hex)
U-Boot> tftp 20000000 dt
macb0: link up, 100Mbps full-duplex (lpa: 0xcde1)
Using macb0 device
TFTP from server 192.168.1.247; our IP address is 192.168.1.240
Filename 'dt'.
Load address: 0x20000000
Loading: #
340.8 KiB/s
done
Bytes transferred = 13279 (33df hex)
U-Boot> bootm 22000000 - 20000000
## Booting kernel from Legacy Image at 22000000 ...
Image Name: Linux-3.16.1
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3067952 Bytes = 2.9 MiB
Load Address: 20008000
Entry Point: 20008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 20000000
Booting using the fdt blob at 0x20000000
Loading Kernel Image ... OK
Loading Device Tree to 23ea3000, end 23ea93de ... OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Error: unrecognized/unsupported device tree compatible list:
[ 'atmel,at91sam9263ek' 'atmel,at91sam9263' 'atmel,at91sam9' ]
Available machine support:
ID (hex) NAME
000004b2 Atmel AT91SAM9263-EK
Please check your kernel config and/or bootloader.
Solution:
Add this line to .config:
CONFIG_MACH_AT91SAM9_DT=y
The correct configuration for this board when using device tree is at91_dt_defconfig.
However, I am quite surprised to see someone trying to use such an old kernel. This board is fully supported upstream. Why don't you use v5.3? If this doesn't work, please report any bug, we will be happy to help correct them.
I am try to understand the build and booting process of Linux kernel for ARM. I took vanila linux from www.kernel.org and build it after run configuration for AT91SAM9260.
In message when we compile the kernel showed that:
==========================================
LD vmlinux
SORTEX vmlinux
SYSMAP System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
GZIP arch/arm/boot/compressed/piggy.gzip
AS arch/arm/boot/compressed/piggy.gzip.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-3.9.1+
Created: Sat Nov 23 18:15:58 2013
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1635544 Bytes = 1597.21 kB = 1.56 MB
Load Address: 20008000
Entry Point: 20008000
Image arch/arm/boot/uImage is ready
==========================================
My questions are:
Image type is uncompressed, this means that we don't compress vmlinux to zImage ?
Load Address: 20008000: this is address of decompressed image = ZRELADDR defined in arch/arm/boot/Makefile ?
This address also is address of ../arm/kernel/head.o ?
It seems that we don't use address KERNEL_PHYS , this method is common way or just for AT91SAM family ?
Basically, our procedures to build and booting are:
a. building kernel steps: vmlinux -> uImage (skip to create zImage).
b. kernel booting steps: DataFlash/NAND --load-->uImage (# 0x22200000) ---decompress--> uncompressed image (# 0x20008000).
In this case, no zImage in booting process although in build message I saw zImage created. I'm wrong ?
4 . How about the address 0xC0008000 which I found in /arch/arm/kernel/vmlinux.lds at line:
. = 0xC0000000 + 0x00008000;
Do we use it ?. I confuse this address with the ZRELADDR.
Regards.
The uImage file has most probably been built using the zImage. It says uncompressed because the uImage itself is not compressed.
The load address can be used by the boot-loader to store data necessary for the early phases of the Linux kernel boot (such as the command line defined in the bootloader.)
You're right about the boot process. But when the zImage is used then the decompression is done by the kernel instead of the bootloader. See decompress_kernel()
The address 0xc0008000 is a virtual address. It maps to the physical address 0x20008000. Virtual addresses can be used only after Linux sets up the memory translation (MMU).
I'm compiling a custom kernel under Ubuntu and I'm running into the problem that my kernel doesn't seem to know where to look for firmware. Under Ubuntu 8.04, firmware is tied to kernel version the same way driver modules are. For example, kernel 2.6.24-24-generic stores its kernel modules in:
/lib/modules/2.6.24-24-generic
and its firmware in:
/lib/firmware/2.6.24-24-generic
When I compile the 2.6.24-24-generic Ubuntu kernel according the "Alternate Build Method: The Old-Fashioned Debian Way" I get the appropriate modules directory and all my devices work except those requiring firmware such as my Intel wireless card (ipw2200 module).
The kernel log shows for example that when ipw2200 tries to load the firmware the kernel subsystem controlling the loading of firmware is unable to locate it:
ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
ipw2200: ipw2200-bss.fw request_firmware failed: Reason -2
errno-base.h defines this as:
#define ENOENT 2 /* No such file or directory */
(The function returning ENOENT puts a minus in front of it.)
I tried creating a symlink in /lib/firmware where my kernel's name pointed to the 2.6.24-24-generic directory, however this resulted in the same error. This firmware is non-GPL, provided by Intel and packed by Ubuntu. I don't believe it has any actual tie to a particular kernel version. cmp shows that the versions in the various directories are identical.
So how does the kernel know where to look for firmware?
Update
I found this solution to the exact problem I'm having, however it no longer works as Ubuntu has eliminated /etc/hotplug.d and no longer stores its firmware in /usr/lib/hotplug/firmware.
Update2
Some more research turned up some more answers. Up until version 92 of udev, the program firmware_helper was the way firmware got loaded. Starting with udev 93 this program was replaced with a script named firmware.sh providing identical functionality as far as I can tell. Both of these hardcode the firmware path to /lib/firmware. Ubuntu still seems to be using the /lib/udev/firmware_helper binary.
The name of the firmware file is passed to firmware_helper in the environment variable $FIRMWARE which is concatenated to the path /lib/firmware and used to load the firmware.
The actual request to load the firmware is made by the driver (ipw2200 in my case) via the system call:
request_firmware(..., "ipw2200-bss.fw", ...);
Now somewhere in between the driver calling request_firmware and firmware_helper looking at the $FIRMWARE environment variable, the kernel package name is getting prepended to the firmware name.
So who's doing it?
From the kernel's perspective, see /usr/src/linux/Documentation/firmware_class/README:
kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device)
userspace:
- /sys/class/firmware/xxx/{loading,data} appear.
- hotplug gets called with a firmware identifier in $FIRMWARE
and the usual hotplug environment.
- hotplug: echo 1 > /sys/class/firmware/xxx/loading
kernel: Discard any previous partial load.
userspace:
- hotplug: cat appropriate_firmware_image > \
/sys/class/firmware/xxx/data
kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
comes in.
userspace:
- hotplug: echo 0 > /sys/class/firmware/xxx/loading
kernel: request_firmware() returns and the driver has the firmware
image in fw_entry->{data,size}. If something went wrong
request_firmware() returns non-zero and fw_entry is set to
NULL.
kernel(driver): Driver code calls release_firmware(fw_entry) releasing
the firmware image and any related resource.
The kernel doesn't actually load any firmware at all. It simply informs userspace, "I want a firmware by the name of xxx", and waits for userspace to pipe the firmware image back to the kernel.
Now, on Ubuntu 8.04,
$ grep firmware /etc/udev/rules.d/80-program.rules
# Load firmware on demand
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware_helper"
so as you've discovered, udev is configured to run firmware_helper when the kernel asks for firmware.
$ apt-get source udev
Reading package lists... Done
Building dependency tree
Reading state information... Done
Need to get 312kB of source archives.
Get:1 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (dsc) [716B]
Get:2 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (tar) [245kB]
Get:3 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2 (diff) [65.7kB]
Fetched 312kB in 1s (223kB/s)
gpg: Signature made Tue 14 Apr 2009 05:31:34 PM EDT using DSA key ID 17063E6D
gpg: Can't check signature: public key not found
dpkg-source: extracting udev in udev-117
dpkg-source: unpacking udev_117.orig.tar.gz
dpkg-source: applying ./udev_117-8ubuntu0.2.diff.gz
$ cd udev-117/
$ cat debian/patches/80-extras-firmware.patch
If you read the source, you'll find that Ubuntu wrote a firmware_helper which is hard-coded to first look for /lib/modules/$(uname -r)/$FIRMWARE, then /lib/modules/$FIRMWARE, and no other locations. Translating it to sh, it does approximately this:
echo -n 1 > /sys/$DEVPATH/loading
cat /lib/firmware/$(uname -r)/$FIRMWARE > /sys/$DEVPATH/data \
|| cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data
if [ $? = 0 ]; then
echo -n 1 > /sys/$DEVPATH/loading
echo -n -1 > /sys/$DEVPATH/loading
fi
which is exactly the format the kernel expects.
To make a long story short: Ubuntu's udev package has customizations that always look in /lib/firmware/$(uname -r) first. This policy is being handled in userspace.
Wow this is very useful information and it led me to the solution for my problem when making a custom USB kernel module for a device requiring firmware.
Basically, every Ubuntu brings a new rehash of hal,sysfs,devfs,udev,and so on...and things just change. In fact I read they stopped using hal.
So let's reverse engineer this yet again so it's pertinent to the latest [Ubuntu] systems.
On Ubuntu Lucid (the latest at time of writing), /lib/udev/rules.d/50-firmware.rules is used. This file calls the binary /lib/udev/firmware, where magic happens.
Listing: /lib/udev/rules.d/50-firmware.rules
# firmware-class requests, copies files into the kernel
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware --firmware=$env{FIRMWARE} --devpath=$env{DEVPATH}"
The magic should be something along these lines (source: Linux Device Drivers, 3rd Ed., Ch. 14: The Linux Device Model):
echo 1 to loading
copy firmware to data
on failure, echo -1 to loading and halt firmware loading process
echo 0 to loading (signal the kernel)
then, a specific kernel module receives the data and pushes it to the device
If you look at Lucid's source page for udev, in udev-151/extras/firmware/firmware.c, the source for that firmware /lib/udev/firmware binary, that's exactly what goes on.
Excerpt: Lucid source, udev-151/extras/firmware/firmware.c
util_strscpyl(datapath, sizeof(datapath), udev_get_sys_path(udev), devpath, "/data", NULL);
if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
err(udev, "error sending firmware '%s' to device\n", firmware);
set_loading(udev, loadpath, "-1");
rc = 4;
goto exit;
};
set_loading(udev, loadpath, "0");
Additionally, many devices use an Intel HEX format (textish files containing checksum and other stuff) (wiki it i have no reputation and no ability to link). The kernel program ihex2fw (called from Makefile in kernel_source/lib/firmware on .HEX files) converts these HEX files to an arbitrary-designed binary format that the Linux kernel then picks up with request_ihex_firmware, because they thought reading text files in the kernel was silly (it would slow things down).
On current Linux systems, this is handled via udev and the firmware.agent.
Linux 3.5.7 Gentoo, I have the same issue.
SOLVED:
emerge ipw2200-firmware
Then go to /usr/src/linux
make menucofig
on device driver, remove all wirless drivers don't needed, set Intell 2200 as module and recompile.
make
make modules_install
cp arch/x86/boot/bzImage /boot/kernel-yourdefault