I am trying to understand how a MLO is loaded into the on-chip of a SOC and do the minimal configuration. I am using TI DM8168 soc.
I have gone through the following link to understand the MLO or x-loader:
http://omappedia.org/wiki/Bootloader_Project
I got to know that the ROM Code loads the MLO (x-loader) to the on-chip RAM of the SoC which do the minimal configuration and finally loads the uboot (universal bootloader), that finally initiates the linux kernel.
My doubt here is that my on-chip RAM size is 64 KB and the MLO size is 116 KB, then how the ROM code is loading the MLO to the on-chip RAM
It seems that the DM8168 has more than 64KiB internal RAM: as explained in
the DM816x AM389x PSP 04.00.01.13 Feature Performance Guide, it has at least two more blocks of internal RAM, referenced OMC0 and OMC1, both being 256KiB in size.
Those two banks can be used by u-boot according to this document:
OCMC0 0x40300000 - 0x4033FFFF OCMC 0 will be used by ROM Code and U-boot. Once Linux kernel boots, OCMC0 is free and kernel can use it. If OCMC0 should not be used to load u-boot if loaded using CCS.
OCMC1 0x40400000 - 0x4043FFFF OCMC 1 will be used by ROM Code and U-boot. Once Linux kernel boots, OCMC0 is free and kernel can use it.
From u-boot-omap3/board/ti/ti8168/config.mk, it seems u-boot is using OMC1
TI_LOAD_ADDR = 0x40400000
This would explain why your 116KiB u-boot image can fit in the DM8168 internal RAM.
Related
I'm trying to write a kernel module for an Intel FPGA design supporting PCIe SR-IOV and placed in the x16 PCIe slot of an IBase M991 Mainboard (Q170 PCH, VT-d activated in BIOS, Integrated graphics only mode enabled).
The CPU is an Intel Core i7-6700TE, which also supports virtualization.
Furthermore I'm using a Yocto - Morty Distribution (Linux Kernel 4.19) with the following Kconfigs enabled:
CONFIG_PCI_IOV=y
CONFIG_PCI_DEBUG=y
CONFIG_INTEL_IOMMU_SVM=y
CONFIG_PCI_REALLOC_ENABLE_AUTO=y
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
CONFIG_IRQ_REMAP=y
CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y
CONFIG_DYNAMIC_DEBUG=y
When doing all of this I see my driver loading (probe function gets called), but after calling pci_enable_sriov with the number of VF I want to activate I get the kernel message
not enough MMIO resources for SR-IOV
What am I doing wrong here? Is there an init function I need to call?
Many thanks for your help.
Edit: More information about the PCIe device:
1 PF, 8 VF
2 BARs (BAR0 and BAR2)
non prefetchable, 32 bit BARs
each BAR size is 4 kB (12bit)
I'm a newbie to Linux
So While booting linux on my "cutom embedded development board" I can see some log
Memory: 405860K/509952K available (2604K kernel code, 188K rwdata, 1068K rodata, 164K init, 131K bss, 87708K reserved, 16384K cma-reserved)
176 Virtual kernel memory layout:
Which means Linux has detected 512MB of RAM,(Eventhough I have 2GB of RAM)
I assume this infomation needs to be passed dtb, can someone help me regarding how this information node looks like and how can I increase the size of it ?
You need to change the memory node, so that the linux can see the 2gb. you can refer this link. Also you might want to set CONFIG_VMSPLIT_2G
While building the kernel I am giving LOADADDR as "0x80008000":
make uImage LOADADDR=0x80008000
Can you please help to understand what is the use of this? Can I change the LOADADDR, is there any restriction on the length of the LOADADDR?
(I'm assuming that you're using ARM based on the mention of U-Boot and the value of LOADADDR.)
Can you please help to understand what is the use of this?
LOADADDR specifies the address where the kernel image will be located by the linker. (This is true for a few architectures (e.g. Blackfin), but not for ARM.
LOADADDR specifies the address where the kernel image will be located by U-Boot and is stored in the U-Boot header by the mkimage utility. Typically the load address (for placement in memory) is also the start address (for execution). Note that the uImage file is typically just the (self-extracting, compressed) zImage file with the U-Boot wrapper.
Can I change the LOADADDR,
Yes, but according to (Vincent Sanders') Booting ARM Linux that would be contrary to ARM convention:
Despite the ability to place zImage anywhere within memory,
convention has it that it is loaded at the base of physical RAM plus
an offset of 0x8000 (32K). This leaves space for the parameter block
usually placed at offset 0x100, zero page exception vectors and page
tables. This convention is very common.
(The uImage mentioned in your question is probably just a zImage with the U-Boot wrapper, so the quotation does apply.)
is there any restriction on the length of the LOADADDR?
The "length"? If you're using a 32-bit processor, then the length of this address would be 32 bits.
ADDENDUM
arch/arm/boot/Makefile only uses LOADADDR for building the uImage from the zImage.
From (Russel King's) Booting ARM Linux the constraints on this LOADADDR are:
The
kernel should be placed in the first 128MiB of RAM. It is recommended
that it is loaded above 32MiB in order to avoid the need to relocate
prior to decompression, which will make the boot process slightly
faster.
When booting a raw (non-zImage) kernel the constraints are tighter.
In this case the kernel must be loaded at an offset into system equal
to TEXT_OFFSET - PAGE_OFFSET.
The expected locations for the Device Tree or ATAGs or an initramfs can add more constraints on this LOADADDR.
Putting this in other terms, kernel compilation can generate different images, compressed or not (i.e. needed for XIP).
LOADADDR is the entry_point of the kernel, must be correct (match with where u-boot loads it in DDR) for certain architectures that compiles with absolute long jumps, and not important at all for ARM that can execute relative jumps.
What is the role of ZTEXTADDR in Linux kernel ?
From lxr.linux.no, it's an address in RAM that holds address of zImage as sequence below?
A.
uImage (DataFlash/NAND) ---load_to_RAM--->
uImage (# boot_addr) ---decompress_uImage-->
zImage (# ZTEXTADDR) --- decompress_zImage--->
uncompressed image (# ZRELADDR).
or just:
B.
uImage (DataFlash/NAND) ---load_to_RAM--->
uImage (# boot_addr) ---decompress_uImage-->
uncompressed image (# ZRELADDR)
no using ZTEXTADDR in new kernel version for booting process ?
The Linux ARM decompression boot loader is capable of relocating itself when running from RAM. The relocation portion is PC-relative and so it can be loaded at any address. However, if your main image starts from FLASH/ROM, the code can not be relocated; while moving an image in RAM is a simple memmove(), it is much more involved for NOR flash and can be impossible for ROM.
In this case, a compressed boot linker script is used with the ZTEXTADDR as the location of the decompression code. In your diagram, you have a u-boot, which will load the uImage. There is no reason to execute this directly from Flash/ROM. u-boot can copy the image to RAM and there is no need for the ZTEXTADDR value and it should be left as zero.
If your image boots directly from Flash/ROM, without a boot loader then ZTEXTADDR is useful,
zImage (in flash) --> decompress vmlinux.bin to RAM --> run kernel
The zImage may need to be annotated with some chip setup for this to work and would need ATAGS or device trees linked. For this reason, there are many machine variants in boot/compressed; This is not maintainable and these type of files are discouraged. Typically another bootloader loads the image to RAM and the zImage can move itself to whatever destination it needs; I think that is your situation and you should set ZTEXTADDR to zero and forget about it.
I have this x86 device and a kernel module that tries to allocate DMA memory. It has a parameter called dmasize that allows to control the size of allocated memory.
I've noticed that allocation succeeds when dmasize=2M but not if larger. Even at boot time.
I heard there was a limitation by CONSISTENT_DMA_SIZE, but looking at lxr, I can't find it for arch x86 kernel 3.2.
Not sure if it is relevant, but this is a 32 bit machine with 8GB of RAM and a pae enabled kernel.
This is the call to dma_alloc_coherent:
dma_addr_t dma_handle;
if (!(_dma_vbase = dma_alloc_coherent(0, alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) {
gprintk("_alloc_mpool: Kernel failed to allocate the memory pool of size 0x%lx\n", (unsigned long)alloc_size);
return;
}
Appreciate anyone who can help with this.
Just in case anyone comes across this, the answer is as follows:
The config flag CONFIG_FORCE_MAX_ZONEORDER which defaults at 11 at most architecture is the cause for this limitation.
increasing it to 12 (and recompiling the kernel) fixes the problem.
I suspect using CMA will also be possible but since my kernel doesn't support it, I cannot say for sure.