Tool to Visualize the Device Tree File (Dtb) Used by the Linux Kernel

Tool to visualize the device tree file (dtb) used by the Linux kernel?

You can try the Component inspector tool.

Sample Image

It is part of QorIQ Configuration Suite which is a plugin for Eclipse.

Download here.
(Requires registration. Free to download.)


Personally as i am on the cmd-line most of the time, and quite addicted to vi, i find its built-in code folding capabilities are somewhat sufficient as long as the dts is properly indented.

Setup hot-keys commands to fold/expand blocks of code in vi
by adding the following lines to .vimrc :

nnoremap <silent> <F5> zfa}<CR>
nnoremap <silent> <F6> zo<CR>

With the above setup, to fold a block/node, simply move the cursor onto any of its lines(except the title) and hit F5. To expand a folded block/node, move to the line with the folded title and hit F6.

Here is what a partially folded dts looks like in vi.
Sample Image

Quick rebuild of device tree only with Yocto/bitbake?

AFAIK there are two different ways of doing this.

  1. The kernel way: Using the scripts provided by the kernel
  • Change to your kernel source directory (<build dir>/tmp/work/<machine>/<kernel-name>/<kernel-version>/git/)
  • Execute the device-tree-compiler: ./scripts/dtc/dtc -I dts -O dtb -o ./devicetree.dtb path/to/devicetree.dts

  1. The bitbake way: Using the kernel's deploy job
  • Call $ bitbake <kernel-name> -f -c deploy
  • The generated device-tree-blob then can be found in <build dir>/tmp/work/<machine>/<kernel-name>/<kernel-version>/build/arch/arm/boot/dts/)

At least for me both versions worked in a quick test.

UPDATE:
I just came over a third version of building the dtb with yocto on the net.
That one uses yocto's devshell of the kernel build.
For more information see the original authors page at https://splefty.blogspot.co.at/2015/09/compiling-device-tree-using-yocto.html.

How can a C application work on multiple cores with gem5?

The application doesn't know that it's being run on a simulated system, so you can treat gem5 as a real system to achieve your goal. i.e., by using OpenMP or MPI.

If the system being modeled has these libraries (OpenMP or MPI) installed then these libraries should work in theory.

How to compile dts Linux device tree source files to dtb?

Device trees do not need to be compiled with "architecture-aware" tools. The dtc compiler on your ubuntu machine is probably current enough to compile your device tree. Or you can download the latest source and compile it yourself. The dtc compiler can be found here:

https://git.kernel.org/pub/scm/utils/dtc/dtc.git

There are some good documents in that package that will help you better understand device trees in general.

It's pretty easy to compile (and disassemble) device trees. For example

$ dtc -O dtb -o p4080ds.dtb p4080ds.dts

To get the device tree in text from from the device tree blob, do this:

$ dtc -I dtb -O dts p4080ds.dtb

Hope this helps!

How to configure Yocto for an example hello world program which uses a Debian library?

Installation & Configuration of Yocto

I.) install toolchain

I.1.) apt-get:

sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat libsdl1.2-dev xterm

I.2.) opt. configure git after proxy

git config --global core.gitproxy <gitproxy>

I.3.) download Toolchain + meta packages and checkout the "right" commit

git clone git://git.yoctoproject.org/poky
cd poky
git checkout jethro

git clone git://github.com/linux4sam/meta-atmel.git
cd meta-atmel
git checkout jethro
cd ..

git clone git://git.openembedded.org/meta-openembedded
cd meta-openembedded
git checkout jethro
cd ..

II.) build kernel+rootfs for SAMA5D3x

II.1) create new project

source oe-init-build-env

the new project is created at the "build" dir
modify layers "conf/bblayers.conf" via commandos

bitbake-layers add-layer "../meta-atmel"
bitbake-layers add-layer "../meta-openembedded/meta-oe"
bitbake-layers add-layer "../meta-openembedded/meta-networking"
bitbake-layers add-layer "../meta-openembedded/meta-python"

edit of "conf/local.conf"

MACHINE ??= "sama5d3xek"
DL_DIR ?= "${TOPDIR}/../downloads"
DISTRO ?= "poky-atmel"

the download directory is outside of the build environment. The downloaded sources can be used for different builds.

II.2) create image

bitbake -c clean core-image-minimal
bitbake core-image-minimal

the result files are created at "tmp/deploy/images/sama5d3xek"

II.3) flash image

The sam-ba tool from Atmel is needed. The Flash-Process can be automated by a script(we create a tcl file). The self written tool "buildAtmelImages.py" copies the needed image files for the SAMA5D35, creates the u-boot configuration and a Flash-Script. An Example:

python buildAtmelImages.py --help
python buildAtmelImages.py -s "/home/user/poky/build/tmp/deploy/images/sama5d3xek" -d "/home/user/images" -t "\\\\1.2.3.4\\admin\\images"

here comes the code for "buildAtmelImages.py":

#!/usr/bin/python
# encoding: utf-8
'''
buildAtmelImages -- make yocto build images ready of the sam-ba flash tool

buildAtmelImages is a description

- reverse engineered /meta-atmel/scripts/nandflash.tcl script
- works only for the SAMA5D35
- params:
-s "<dir>" = source dir of the images generated by yocto. like "/home/user/poky/build/tmp/deploy/images/sama5d3xek"
-d "<dir>" = destination dir
-t "<dir/url>" = tcl refence dir. The path to the images, used to flash, is hard coded in the tcl script. typical example "\\\\192.168.1.2\\admin\\images" for an samba based network
- way of operation:
# hints:
I.) the SAMA5D3x implements some ECC features. This means that in every NAND sector are bits for error correction reserved.
This acts into 2 directions:
1.) the binary files have to be flashed by takeing care of the extra ECC bits. This is done by the sam-ba flash tool
2.) the kernel needs to take care, that the data stored on the NAND drive has some extra handling. This is managed by the meta-atmel package used by the yocto toolchain.

II.) u boot configuration
1.) the u boot configuration is placed into the NAND. But the configuration is not generated by the yocto toolchain. Atmel delivers a flashing script for its demo boards. This was reversed engineered into this python script.
The layout of the boot config is a defined memory space which is guared by an crc32(litle endian). The boot configuration is placed as ANSII string parameters. These parameters are seperated by a zero.

2.) because of the ecc the binary device tree(dtb) and kernel needs to be copied to memory before been executed. For that it is needed that u-boot loads them into ram before starting the kernel.

# operation:
First the generated images are copied. After the configuartion is generated and placed into the output dir. At least the tcl script is generated and placed into the output dir, as well.

@author: Stefan Jaritz

@copyright:

@license: license

@contact:
@deffield updated: Updated
'''

import sys
import os
import shutil
import binascii
import struct

from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter

__all__ = []
__version__ = 0.1
__date__ = '2016-04-19'
__updated__ = '2016-04-19'

class _memorySeg():
def __init__(self, add, sf, df):
self.add = add
self.sf = sf
self.df = df

gArch = 'sama5d3xek'

gTCLfilename = 'SEK4.tcl'

gMemSetup = {
'bootloader' : _memorySeg(0x00000000, 'at91bootstrap-sama5d3xek.bin', 'bootloader.bin'),
'uboot' : _memorySeg(0x00040000, 'u-boot-sama5d3xek.bin', 'uboot.bin'),
'ubootEnv' : _memorySeg(0x000c0000, None, 'ubootEnv.bin'),
'ubootEnvRed' : _memorySeg(0x00100000, None, 'ubootEnv.bin'),
'dtb' : _memorySeg(0x00180000,'zImage-sama5d35ek.dtb', 'kernel.dtb'),
'kernel' : _memorySeg(0x00200000,'zImage', 'kernel'),
'rootfs' : _memorySeg(0x00800000,'core-image-minimal-sama5d3xek.ubi', 'rootfs.ubi')
}

gSourceDir = ''
gDestDir = ''
gTCLfilepath = ''

gECCcnfg = {
'at91sam9x5ek' : 0xc0c00405,
'at91sam9n12ek' : 0xc0c00405,
'sama5d3xek' :0xc0902405,
'sama5d3_xplained' : 0xc0902405,
'sama5d4ek' : 0xc1e04e07,
'sama5d4_xplained' : 0xc1e04e07
}

def _copyFiles ():
''' copies image files from source to the destination'''
global gMemSetup

for (k, ms) in gMemSetup.items():
if ms.sf is not None:
print("copy {k}".format(k=k))
shutil.copy(os.path.join(gSourceDir, ms.sf), os.path.join(gDestDir, ms.df))

def _genUBootCfg ():
global gMemSetup
global gSourceDir
global gDestDir

print("generate u-boot config")

bootCfgStr = "bootcmd=nand read 0x{dtbLoadAddr:X} 0x{dtbAddr:X} {dtbSize}; nand read 0x{kernelLoadAddr:X} 0x{kernelAddr:X} {kernelSize}; bootz 0x{kernelLoadAddr:X} - 0x{dtbLoadAddr:X}".format(
dtbLoadAddr=0x21000000,
dtbAddr=gMemSetup['dtb'].add,
dtbSize=os.path.getsize(os.path.join(gSourceDir, gMemSetup['dtb'].sf)),
kernelLoadAddr=0x22000000,
kernelAddr=gMemSetup['kernel'].add,
kernelSize=os.path.getsize(os.path.join(gSourceDir, gMemSetup['kernel'].sf))
)

bootVars = (
'bootdelay=0',
'baudrate=115200',
'stdin=serial',
'stdout=serial',
'stderr=serial',
'bootargs=console=ttyS0,115200 mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs rw',
bootCfgStr
)

cfgMemCfg = bytearray(0x20000-5)
l = len(cfgMemCfg)
indx = 0
for v in bootVars:
l = len(v)
cfgMemCfg[indx:indx+l] = v.encode('utf-8')
indx += l + 1

crc = binascii.crc32(cfgMemCfg)

with open(os.path.join(gDestDir, gMemSetup['ubootEnv'].df), mode='wb') as f:
# crc32 as little endian
f.write(struct.pack('<I',crc))
f.write(bytearray(1))
f.write(cfgMemCfg)
f.close()

def _helper_genTCLFilename (idName):
pstr = os.path.join(gTCLfilepath ,gMemSetup[idName].df)
pstr = pstr.replace('/', '\\')
return pstr.replace('\\', '\\\\')

def _genFlashScript():
global gMemSetup
global gECCcnfg
global gTCLfilename
global gDestDir
global gArch

print("generate tcl script for sam-ba")

tclStr = """puts "-I- start flashing"
NANDFLASH::Init
NANDFLASH::NandHeaderValue HEADER 0x{pmeccConfig:X}
NANDFLASH::EraseAllNandFlash
NANDFLASH::SendBootFilePmeccCmd "{bootstrapFile}"
send_file {{NandFlash}} "{ubootFile}" 0x{ubootAddr:X} 0
send_file {{NandFlash}} "{ubootEnvFile}" 0x{ubootEnvAddr:X} 0
send_file {{NandFlash}} "{ubootEnvFileRed}" 0x{ubootEnvAddrRed:X} 0
send_file {{NandFlash}} "{dtbFile}" 0x{dtbAddr:X} 0
send_file {{NandFlash}} "{kernelFile}" 0x{kernelAddr:X} 0
NANDFLASH::NandSetTrimffs 1
send_file {{NandFlash}} "{rootfsFile}" 0x{rootfsAddr:X} 0
puts "-I- finished flashing"
""".format(
pmeccConfig=gECCcnfg[gArch],
bootstrapFile=_helper_genTCLFilename('bootloader'),
ubootFile=_helper_genTCLFilename('uboot'),
ubootAddr=gMemSetup['uboot'].add,
ubootEnvFile=_helper_genTCLFilename('ubootEnv'),
ubootEnvAddr=gMemSetup['ubootEnv'].add,
ubootEnvFileRed=_helper_genTCLFilename('ubootEnvRed'),
ubootEnvAddrRed=gMemSetup['ubootEnvRed'].add,
dtbFile=_helper_genTCLFilename('dtb'),
dtbAddr=gMemSetup['dtb'].add,
kernelFile=_helper_genTCLFilename('kernel'),
kernelAddr=gMemSetup['kernel'].add,
rootfsFile=_helper_genTCLFilename('rootfs'),
rootfsAddr=gMemSetup['rootfs'].add
)

with open(os.path.join(gDestDir, gTCLfilename), mode='w') as f:
f.write(tclStr)
f.close()

class _CLIError(Exception):
'''Generic exception to raise and log different fatal errors.'''
def __init__(self, msg):
super(_CLIError).__init__(type(self))
self.msg = "E: %s" % msg
def __str__(self):
return self.msg
def __unicode__(self):
return self.msg

def main(argv=None): # IGNORE:C0111
'''Command line options.'''
global gSourceDir
global gDestDir
global gTCLfilepath

if argv is None:
argv = sys.argv
else:
sys.argv.extend(argv)

program_name = os.path.basename(sys.argv[0])
program_version = "v%s" % __version__
program_build_date = str(__updated__)
program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
program_license = '''%s

Created by Stefan Jaritz on %s.
Copyright 2016 organization_name. All rights reserved.

Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0

Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.

USAGE
''' % (program_shortdesc, str(__date__))

try:
# Setup argument parser
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
parser.add_argument("-s", "--source", dest="srcD", help="source path of the images [default: %(default)s]", default=os.getcwd())
parser.add_argument("-d", "--destination", dest="dstD", help="destination where the images and the flash script is copied [default: %(default)s]", default=os.getcwd() )
parser.add_argument("-t", "--tclFilePath", dest="tclD", help="TCL script path. The path where the TCL file gona be located [default: %(default)s]", default='' )
parser.add_argument('-V', '--version', action='version', version=program_version_message)

# Process arguments
args = parser.parse_args()
gSourceDir = args.srcD
gDestDir = args.dstD
gTCLfilepath = args.tclD

shutil.rmtree(gDestDir, ignore_errors=True)
os.makedirs(gDestDir)
print("start")

_copyFiles()
_genUBootCfg()
_genFlashScript()

print("finished")
return 0
except KeyboardInterrupt:
### handle keyboard interrupt ###
return -1
except Exception as e:
indent = len(program_name) * " "
sys.stderr.write(program_name + ": " + repr(e) + "\n")
sys.stderr.write(indent + " for help use --help")
return -2

if __name__ == "__main__":
sys.exit(main())

III.) Create own package

yocto-layer create own
bitbake-layers add-layer "../meta-own"

modify the example.bb

SRC_URI = "file://testFTP.c"

S = "${WORKDIR}"

DEPENDS ="curl"

do_compile() {
${CC} testFTP.c -o testFTP ${CFLAGS} -lcurl
}

do_install() {
install -d ${D}${bindir}
install -m 0755 testFTP ${D}${bindir}
}

now add in "layer.conf"

IMAGE_INSTALL_append = " vim testftp"

Now the vim editor and the testftp recipe, which includes the testFTP binary is installed at the "user/bin" at the rootfs.

After the flashing, start the the SAMA5D35 Evalboard. Login as "root". Type: "testFTP" or "vim" and enjoy the output.

Cheers!



Related Topics



Leave a reply



Submit