Kernel / Linux location is memory, how to verify - linux

I'm running linux on a Atlas-SoC Kit/DE0-Nano-SoC Kit.
Through u-boot I've placed the kernel at a different location.
mcboot=setenv bootargs console=ttyS0,115200 root=${mmcroot} rw rootwait;bootz ${loadaddr} - ${fdtaddr}
mmcload=mmc rescan;${mmcloadcmd} mmc 0:${mmcloadpart} ${loadaddr} ${bootimage};${mmcloadcmd} mmc 0:${mmcloadpart} ${fdtaddr} ${fdtimage}
mmcloadcmd=fatload
mmcloadpart=1
mmcroot=/dev/mmcblk0p2 mem=744M memmap=744M$256M
the last line, request 744M starting at 256M offset.
No my question is, how can i verify that this actually happend? This since i'm reading mixed solutions online between using device-tree and memmap configurations. And i want to make sure, before i continue on writing the device driver section.
My /proc/iomem:
root#cyclone5:~# cat /proc/iomem
00000000-2e7fffff : System RAM
00008000-0077656f : Kernel code
007d6000-00859433 : Kernel data
ff702000-ff703fff : /soc/ethernet#ff702000
ff704000-ff704fff : /soc/dwmmc0#ff704000
ffb40000-ffb4fffe : /soc/usb#ffb40000
ffc00000-ffc00fff : c_can_platform
ffc02000-ffc0201f : serial
ffc04000-ffc04fff : /soc/i2c#ffc04000
ffc05000-ffc05fff : /soc/i2c#ffc05000
ffd02000-ffd02fff : /soc/wd#ffd02000
ffe01000-ffe01fff : /soc/amba/pdma#ffe01000
fff01000-fff01fff : fff01000.spi
ffff0000-ffffffff : /soc/sram#ffff0000
any detailed explanations would be highly appreciated,
regards Auke

Device tree and kernel parameter memmap both helps in reserving memory that will not be used by linux kernel. Take a look at linux device tree memory documentation and kernel parameters.
You can use Emulator or high end debugger for example Trace32 to see memory contents.

Related

How does linux bootloaders load vmlinux file to memory when elf file is specified using virtual address and MMU is not set before kernel loading?

I'm confused. When I see /boot/grub/grub.cfg on my x86_64 ubuntu machine, the grub uses vmlinuz-4.15-..-generic file as kernel image. vmlinuz will be a compressed file of vmlinux and vmlinux is elf file having many object codes and data in many sections. And the addresses in the elf file is 'virtual' address not physical. The virtual -> physical address translation is done through page table and MMU hardware which is set by the kernel.
This is the start of decoded code from vmlinux for aarch64.(I got this from aarch64-none-elf-objdump -D vmlinux)
ffff800010080000 <_text>:
ffff800010080000: 91005a4d add x13, x18, #0x16
ffff800010080004: 1447ffff b ffff800011280000 <stext>
ffff800010080008: 00080000 .inst 0x00080000 ; undefined
ffff80001008000c: 00000000 .inst 0x00000000 ; undefined
ffff800010080010: 01938000 .inst 0x01938000 ; undefined
the kernel text starts at virtual address 0xffff800010080000. Before kernel is executed, and so before page table and MMU setting is done, how does the bootloader place the kernel image's various sections to each virtual address? I guess I'm not aware of a very import thing here. Please someone help me. Or, does the bootloader set up mmu table?(On second thought, I guess this may be the only solution)

crashkernel not starting after crash

I am trying to start a crash kernel using Linux's Kernel Crash Dump. Both of the host and crash kernel are compiled linux-4.13.16 kernel. Unfortunately, the crash kernel fails to start after the crash occurs.
iomem reports reserved space for crash kernel and kdump reports its ready for kdump:
28000000-37ffffff : Crash kernel
$ sudo kdump-config show
DUMP_MODE: kdump
USE_KDUMP: 1
KDUMP_SYSCTL: kernel.panic_on_oops=1
KDUMP_COREDIR: /var/crash
crashkernel addr: 0x28000000
/var/lib/kdump/vmlinuz: symbolic link to /boot/vmlinuz-4.13.16ksa
kdump initrd:
/var/lib/kdump/initrd.img: symbolic link to /var/lib/kdump/initrd.img-4.13.16ksa
current state: ready to kdump
kexec command:
/sbin/kexec -p --command-line="BOOT_IMAGE=/boot/vmlinuz-4.13.16ksa root=UUID=3254c608-d885-4dfc-b20b-fa4e69564dca ro quiet splash vt.handoff=7 irqpoll noirqdistrib nr_cpus=1 nousb systemd.unit=kdump-tools.service" --initrd=/var/lib/kdump/initrd.img /var/lib/kdump/vmlinuz
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.13.16ksa root=UUID=3254c608-d885-4dfc-b20b-fa4e69564dca ro quiet splash crashkernel=384M-2G:128M,2G-:256M vt.handoff=7
After triggering crash using sysrq-trigger, it doesn't load crash kernel.
I have tested with a generic kernel, linux-4.8.0-36-generic, which successfully works.
Syslog file are here.
Both linux-4.8.0-36-generic and linux-4.13.16ksa has same .config file. Only difference I can see is that during boot, for linux-4.13.0-38, it loads the efi.signed vmlinuz(vmlinuz-4.13.0-38-generic.efi.signed) where as the compiled linux-4.13.16ksa is not efi signed.
Can it be an issue? How can I resolve this?

Running Linux 4.9 on Cortex-M4 STM32F4 (29I-DISC1)

I spend a few days trying to understand but I'm stuck.
I get no more than a "Starting kernel..." message after entering 'bootm 8100000' on my STM32F429I-DISC1 board.
Before I update uboot from 2011 to 2016 It was a "Starting Kernel..." + UNHANDED EXCEPTION HARDFAULT, but now I have just the "Starting Kernel..." message.
MCU is a stm32F429, 2MB Flash + ext. 8MB RAM.
Flash start addr is 0x08000000 (uboot addr) and I put my kernel on the start of the 2nd flash bank at 0x08100000.
Start of External 8MB RAM is 0xD0000000
u-boot-2016.11 seems to run pretty well on that board, bdi give me:
U-Boot > bdi
arch_number = 0x00000000
boot_params = 0xD0000100
DRAM bank = 0x00000000
-> start = 0xD0000000
-> size = 0x00800000
current eth = unknown
ip_addr = <NULL>
baudrate = 115200 bps
relocaddr = 0xD07D6000
reloc off = 0xC87D6000
irq_sp = 0xD05D3EE0
sp start = 0xD05D3ED0
Early malloc usage: e0 / 400
This is how I build the kernel:
make CROSS_COMPILE=arm-none-eabi- ARCH=arm uImage LOADADDR=08100000 -B
And this is the complete output of bootm command:
U-Boot > bootm 8100000
## Booting kernel from Legacy Image at 08100000 ...
Image Name: Linux-4.9.0
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 839872 Bytes = 820.2 KiB
Load Address: 08100000
Entry Point: 08100000
Verifying Checksum ... OK
Loading Kernel Image ... OK
Starting kernel ...
With the 'robutest'/'emcraft' kernel/config files I got the same log, unless the Entry Point seems more correct because it's 08100001.
On the robutest/emcraft kernel I tried to activate the LCD screen of the board, but nothing happen.
In all my test I activate kernel config "early printk" and "DEBUG_LL_xxx" stuff.
This is a link to my .config file:
http://pastebin.com/gBNYx3Gs
PS: I made some try with uCLinux emcraft/robutest to try to find what's going on, but my main goal is to run Linux 4.9.
Thanks for reading me!!!
EDIT: I tried to pass the dtb "the old way", but with the same result:
U-Boot > bootm 08100000 - 08040000
## Booting kernel from Legacy Image at 08100000 ...
Image Name: Linux-4.9.0
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 805744 Bytes = 786.9 KiB
Load Address: 08100000
Entry Point: 08100000
Verifying Checksum ... OK
## Flattened Device Tree blob at 08040000
Booting using the fdt blob at 0x8040000
Loading Kernel Image ... OK
Loading Device Tree to d05ce000, end d05d2a9f ... OK
Starting kernel ...
I'm desperate, any ideas is welcome :'(
EDIT2: I tried to uncompress the kernel with u-boot, it's the same:
U-Boot > bootm 8100000 - 8040000
## Booting kernel from Legacy Image at 08100000 ...
Image Name: uImage
Image Type: ARM Linux Kernel Image (gzip compressed)
Data Size: 940696 Bytes = 918.6 KiB
Load Address: d0008000
Entry Point: d0008001
Verifying Checksum ... OK
## Flattened Device Tree blob at 08040000
Booting using the fdt blob at 0x8040000
Uncompressing Kernel Image ... OK
Loading Device Tree to d05ce000, end d05d2a9f ... OK
Starting kernel ...
EDIT3: I checked the memory/USART1 address in the dtb, and it's ok. Why I have no message of the kernel?
EDIT4: With uxipImage:
U-Boot > bootm 08060000 - 08040000
## Booting kernel from Legacy Image at 08060000 ...
Image Name: uxipImage
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1497396 Bytes = 1.4 MiB
Load Address: 08060000
Entry Point: 08060041
Verifying Checksum ... OK
## Flattened Device Tree blob at 08040000
Booting using the fdt blob at 0x8040000
Loading Kernel Image ... OK
Loading Device Tree to d05ce000, end d05d2a9f ... OK
Starting kernel ...
I tried with different entry points, 08060000, 08060040 and 08060041.
I found!
Thanks alexander, the trick for the UART WORKS like a charm!!!!
Thanks to you, First time I try to hack the kernel in an embedded system and I've learnt so many things thanks to you.
For those who will have this problem, for me it was the XIP_PHYS_ADDR!
Don't forget the 64 bytes header!!
I was flashing the XIP kernel # 0x08060000 so the XIP_PHYS_ADDR (and the boot entry btw) it's 0x08060040!!!!
Thank you again alexander !!
I have had faced the same issue but the reason was a different one. The issue was in one of the u-boot structure field that stores the size of the uncompressed linux kernel. The u-boot is not populating this field with the uncompressed size, that the linux kernel uses later to resize its stack, thus putting the system into an undefined state.
Once u-boot prints the Starting kernel... message, the next message should be Uncompressing Linux... done, booting the kernel after u-boot transfers a SMM Handler for the kernel to take-over the execution, and maybe the kernel is looking for this field. If you are working on a x86 based system,the uncompression would be in the following file directories:
arch/x86/boot/uncompressed/head_32.S
arch/x86/boot/uncompressed/piggy.S
The solution is to use the latest u-boot foun in here: https://github.com/andy-shev/u-boot
However, if you are using a custom u-boot, you need to look for this field.

What does udev need to startup properly in Linux?

I have an issue with udev startup on my i.MX6 board. udev-182 was cross-built by the Yocto 1.8 BSP for the board. I see the following output on startup:
INIT: version 2.88 booting
Starting udev
udevd[188]: bind failed: No such file or directory
error binding udev control socket
udevd[188]: error binding udev control socket
I believe the error is a result of the lack of /run/udev/control existing. But I am unsure what creates that.
I noticed this while I was looking into an issue with my touchscreen not working. If I manually restart udev from the command line, everything seems to work fine and my touchscreen begins functioning.
root#nitrogen6x:~# /etc/init.d/udev restart
Stopping udevd
Starting udev
udevd[451]: starting version 182
mxc_v4l_open: Mxc Camera no sensor ipu1/csi0
mxc_cam_select_input: input(0) CSI IC MEM
mxc_v4l_open: Mxc Camera no sensor ipu0/csi0
mxc_v4l_open: Mxc Camera no sensor ipu0/csi1
When I do a restart, /run/udev/control is created.
Any ideas on what could be causing this failure?
Thanks
I had the same issue and I managed to resolve that by appending rootwait rw to my bootargs in u-boot.
For instance, if your bootargs were:
console=ttymxc3,115200 root=/dev/mtdblock4 rootfstype=jffs2 mtdparts=spi0.0:512k(uboot),256k(ubootenv),6144k(kernel),256k(fdt),20m(rootfs),-(data)
Change it to:
console=ttymxc3,115200 root=/dev/mtdblock4 rootfstype=jffs2 rootwait rw mtdparts=spi0.0:512k(uboot),256k(ubootenv),6144k(kernel),256k(fdt),20m(rootfs),-(data)
That's because the kernel mounts the rootfs as r/o by default and thus new files cannot be created by any process at startup.
Compare strace output of "udev start by init" and "udev start from console" might give you some idea.

why does the i2cdetect always gives UU on my RTC in embedded Linux

I'd like to communicate read from my RTC in C code rather than the "hwclock" shell command.
However, when I use i2cdetect, it shows 0x68(which is my RTC slave address) is having the status "UU", which means "Probing was skipped, because this address is currently in use by a driver". And after I tried the i2cget, its givng "could bot set address to 0x68: Device or resource busy".
So I'm thinking if there are some problem in my Linux kernel that will force to read from my RTC all the time, or some other reason.
Thanks
I am assuming that you are using DS-1307 RTC, or one of its variants (because of 0x68 slave address). Check if its driver is loaded by:
$ lsmod | grep rtc
If you seen an entry of rtc_ds1307, (like this -> rtc_ds1307 17394 0 ) in the output of above command then this driver might be in hold of that address.
If the driver is loaded in system then unload it using
$ rmmod rtc-ds1307
EDIT:
(In light of OP's feedback,) Please do the following
1) cat /sys/bus/i2c/devices/3-0068/modalias. This will give you the name of the kernel driver that is keeping this device busy. Copy the driver-name after the colon(:)
OP's output of the command tells us that its ds1337
2) Check if ds1337 is an alias for a driver, using
grep ds1337 /lib/modules/`uname -r`/modules.alias
Hopefully you will get the following output
alias i2c:ds1337 rtc_ds1307
This confirms our presumption that rtc_ds1307 is infact the driver in hold of the I2C address 0x68.
3) use rmmod rtc_ds1307 to unload the driver.
Note: This will only work if the driver is a Loadable Kernel Module, otherwise you will see the following error:
ERROR: Module rtc_ds1307 does not exist in /proc/modules
In that case you will have to recompile the kernel again with that driver disabled/modularized.
0x68 is being used by some driver,
Disable that driver in kernel source code and recompile source code.

Resources