How to cross-compile Embedded Linux (Part 2): Kernel
Audio : Listen to This Blog.
This is the continuation of series of blogs about cross compiling, loading bootloader, Linux kernel and filesystem into an embedded development platform. Please check the previous blog for the target hardware and setup that is needed.
In short, the embedded development platform is beaglebone black with MicroSD card. We have already partitioned the card in the first blog and please look into it for more info.
Topics discussed in this document:
- A little bit about Linux kernel
- Getting the kernel source code
- Get the proper config and start the compilation.
- Setup the toolchain
- Compiling the kernel
- Flashing the kernel image
A little bit about Linux kernel
Linux Kernel is the biggest open source project for starters. This is the most dominant OS in the world (Yep, not windows!) and is the de facto platform which the embedded designers choose nowadays even for real time purposes.Even if you haven’t actually heard about it, using an android based smartphone means you are using a Linux kernel already. The Internet literally runs on machines based on Linux kernel. Let’s put it this way, the IT world depends on Linux to achieve its functionality. 98% of the TOP500 supercomputers use Linux as the core O.S. It runs on various embedded devices such as routers, wireless access points, smart TVs, NAS appliances and the list goes on and on.
The Linux kernel was created in 1991 by Linus Torvalds for his personal use and he released the source as free software under the GPL license to the open source world. After that, many people contributed code to the project and has since expanded to support large number of computer architectures. Linux rapidly attracted developers and users who adopted it as the kernel for other free software projects. The whole development activity is carried out through emails and patches.The Linux kernel has received contributions from nearly 10,000 programmers from more than 1,000 companies, including some of the largest software and hardware vendors.
Getting the kernel source code
The best place to get the kernel source code is from www.kernel.org website. It is always a good option to choose the stable version of the kernel, and the current stable kernel version is 4.8.7 (at the time when this document is written). Below is command for getting the 4.8.7 stable kernel version.
[email protected]:~/git$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.8.7.tar.xz
Please look into the website to know more about available list of releases.
The kernel source comes in compressed version, we can Untar and list the contents of the archive.
[email protected]:~/git$ tar xf linux-4.8.7.tar.xz [email protected]:~/git$ cd linux-4.8.7/
The directory structure looks very similar to the U-Boot bootloader which we have already seen. In fact U-boot took Linux kernel as reference and migrated to this format. Since many of the directories were explained in the U-Boot blog itself let us look into the details about the missing ones.
block –> Contains support for block devices.
crypto –> Contains support for cryptography. Linux kernel supports a large set of cryptographic algorithms and its supported protocols. Many modifications are made for each and every release. If you deeply look into the cryptographic support provided by the kernel you will understand why Linux kernel is one of the safest kernel’s to use.
drivers –> Contains support for humongous set of peripherals devices. This contains almost 60 percent of the kernel code.
firmware –> Contains binary or hex files that should be loaded onto the devices when they come up. This can happen either on boot or when the device is inserted into the target. These are mostly provided by the device vendor itself.
fs –> Contains support for a large set of filesystem. This is also another major portion of the kernel code. Linux kernel has the best support when it comes to filesystem. In fact, Linux kernel provides the best possible filesystem support of all the O.S that exists in the world today.
init –> Contains the initialization code which is non architecture specific. Most subsystems are initialized from here like interrupts, software interrupts, memory management, timers etc.
kernel –> Contains the actual kernel related code like scheduler, timer, irqs and threads. You will be surprised to see that the kernel directory contains a small list of files only.
lib –> Contains support for libraries. These are helper library functions which includes support for algorithms used for encryption, checking the integrity of the files and etc.
mm –> Contains code related to the memory management. This is a very important feature of the Linux kernel. Virtual memory is one key functionality provided by the modern OSes today. This is very much architecture specific and a very complex subject to discuss. ARM processors with MMU can support upto 3 levels of page tables which is pretty much complex.
net –> Contains code for networking support. This is also another major subsystem in the Linux kernel. Almost all the networking protocols are supported by the kernel and internet literally runs with the support of Linux.
The other directories are self explanatory.
Get the proper config and start the compilation
As with the bootloader each boards are categorized by a specific config file which comes with the Linux kernel itself. It is best advised to use the already available config file as it has been tested and is known to be working. All the configs files related to development platform are stored in their corresponding architecture specific directory.
For example, in case of ARM processor, all related boards configs are kept at arch/arm/configs/. You can check this for other architectures also.
[email protected]:~/git/linux-4.8.7$ ls arch/arm/configs/ -l
The above command gives us the list of available config files supported by this kernel. In this plethora of config files, “omap2plus_defconfig” is the config file which we need to use.
Setup the toolchain
As we have downloaded the toolchain and untarred it for compiling the bootloader we need to do almost exactly the same setup here too, to compile the kernel. We need to setup the cross toolchain path so that it compiles the kernel.
Below are the command for our machine:
[email protected]:~/git/u-boot$ export PATH=/home/kasi/git/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin:$PATH; [email protected]:~/git/u-boot$ export CROSS_COMPILE=arm-linux-gnueabihf- [email protected]:~/git/u-boot$ export ARCH=arm;
After setting up the cross tool, we can now use the already available config file to create a .config file.
[email protected]:~/git/linux-4.8.7$ make omap2plus_defconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf # # configuration written to .config # [email protected]:~/git/linux-4.8.7$
The output shows that the .config file was created.
Let us check a few things here. When you execute the below command it will show the list of options/selections available for this kernel.
[email protected]:~/git/linux-4.8.7$ make menuconfig
Few things to note from the above image, at the top left corner it should show the architecture version for which we are compiling. In our case it is showing as ARM and it is the correct one. If it shows as x86 or anything else, then the cross toolchain path has not been setup correctly. We can now exit this menu and start the compilation.
Please look into the available options as it will help you to get a better understanding.
Compiling the kernel
[email protected]:~/git/linux-4.8.7$ make uImage dtbs LOADADDR=0x80008000
uImage –> Creates a kernel image which contains headers understood by U-Boot.
dtbs –> Compile the device tree blobs.
LOADADDR –> It is the physical address from which the kernel should start executing.
The above command will start the compilation process. It may take from few minutes to hours to compile the kernel depending upon the build machine hardware specs and the list of options we have chosen this kernel to support. In the below case it took 12 to 15 minutes to compile the kernel.
scripts/kconfig/conf --silentoldconfig Kconfig CHK include/config/kernel.release WRAP arch/arm/include/generated/asm/clkdev.h WRAP arch/arm/include/generated/asm/bitsperlong.h AS arch/arm/boot/compressed/piggy.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready UIMAGE arch/arm/boot/uImage "mkimage" command not found - U-Boot images will not be built arch/arm/boot/Makefile:77: recipe for target 'arch/arm/boot/uImage' failed make: *** [arch/arm/boot/uImage] Error 1 arch/arm/Makefile:330: recipe for target 'uImage' failed make: *** [uImage] Error 2 [email protected]:~/git/linux-4.8.7$
If you get an error like this don’t panic. Actually it needs a tool “mkimage” with which it should be able to create the uImage. It is provided by the package u-boot-tools.
Dependency installation (if any)
[email protected]:~/git/linux-4.8.7$ sudo apt install u-boot-tools
Now rerun the above make command again so that uImage is created.
[email protected]:~/git/linux-4.8.7$ make uImage dtbs LOADADDR=0x80008000 CHK include/config/kernel.release CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h CHK include/generated/timeconst.h CHK include/generated/bounds.h CHK include/generated/asm-offsets.h CALL scripts/checksyscalls.sh CHK include/generated/compile.h CHK kernel/config_data.h Kernel: arch/arm/boot/Image is ready Kernel: arch/arm/boot/zImage is ready UIMAGE arch/arm/boot/uImage Image Name: Linux-4.8.7 Created: Tue Nov 15 11:40:41 2016 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 3852856 Bytes = 3762.55 kB = 3.67 MB Load Address: 80008000 Entry Point: 80008000 Kernel: arch/arm/boot/uImage is ready
We have compiled our own Linux kernel image. The image should be available in
“arch/arm/boot/” and the device tree blobs should be available in “arch/arm/boot/dts/“. The device tree blob which belongs to BBB is “am335x-boneblack.dtb“.
Flashing the kernel image
There are many to ways to test the built kernel image. If we are early in our development phase and trying to freeze on a kernel version to choose then it would be better to boot the built kernel through tftp. From U-Boot cli, using tftp we can directly load the uImage and dtbs into the RAM and start execution from there. If there are any issues with kernel like crashes or it doesn’t load any subsystem or if you want to try any other kernel version it is as easy as resetting the device and from U-Boot prompt try to loading another kernel image of your choice. This kind of development is very fast and a much preferred one. We are not going to follow that procedure here. We are going to load the kernel image into the Micro SD card and make sure the boot loader loads the uImage from there. It is like having a static image that we don’t want to change with time. As you can guess in this method you can stop any time in the bootloader prompt and try to load the kernel image which you want to test.
Since we have decided to boot from Micro SD card we need to copy these images into the MicroSD card’s boot partition (partition type FAT16 with boot flag set). We need to add one more file by the name uEnv.txt to the boot partition. We can create this file in our build machine, copy the below contents to that file and then copy the file back to the Micro SD card’s boot partition.
msys_kernel=fatload mmc 0 0x80008000 uImage msys_dtb=fatload mmc 0 0x88008000 am335x-boneblack.dtb msys_load=bootm 0x82000000 - 0x88000000 uenvcmd=run msys_kernel; run msys_dtb; run msys_load;
After copying the uEnv.txt file to the Micro SD card the contents of the boot partition should be like this.
[email protected]:~/git/linux-4.8.7$ ls /media/kasi/BOOT/ am335x-boneblack.dtb MLO u-boot.img uEnv.txt uImage
And the contents of the txt file should read like this.
[email protected]:~/git/linux-4.8.7$ cat /media/kasi/BOOT/uEnv.txt msys_kernel=fatload mmc 0 0x80008000 uImage msys_dtb=fatload mmc 0 0x88008000 am335x-boneblack.dtb msys_load=bootm 0x80008000 - 0x88008000 uenvcmd=run msys_kernel; run msys_dtb; run msys_load;
Now remove the Micro SD card, insert it in the target and follow the procedure to boot from Micro SD card. It should boot with the kernel which we have compiled.
Few points to note if no log messages are seen in the serial port
If the kernel is not booting up, then try to change the cmdline parameter:
Default will be like:
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
Now change this to:
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO0,115200"
This is the bootlog for the kernel which is loading.
U-Boot SPL 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35) ############################ ##### MSYS Technologies #### ##### We were here #### ############################ Trying to boot from MMC1 reading uboot.env ** Unable to read "uboot.env" from mmc0:1 ** Using default environment reading u-boot.img reading u-boot.img reading u-boot.img reading u-boot.img U-Boot 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35 +0530) CPU : AM335X-GP rev 2.0 Model: TI AM335x BeagleBone Black DRAM: 512 MiB NAND: 0 MiB MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 reading uboot.env ** Unable to read "uboot.env" from mmc0:1 ** Using default environment not set. Validating first E-fuse MAC Net: eth0: [email protected] Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device SD/MMC found on device 0 reading boot.scr ** Unable to read file boot.scr ** reading uEnv.txt 193 bytes read in 7 ms (26.4 KiB/s) Loaded env from uEnv.txt Importing environment from mmc0 ... Running uenvcmd ... reading uImage 3852896 bytes read in 252 ms (14.6 MiB/s) reading am335x-boneblack.dtb 34185 bytes read in 8 ms (4.1 MiB/s) ## Booting kernel from Legacy Image at 80008000 ... Image Name: Linux-4.8.7 Created: 2016-11-15 9:57:37 UTC Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 3852832 Bytes = 3.7 MiB Load Address: 80008000 Entry Point: 80008000 Verifying Checksum ... OK ## Flattened Device Tree blob at 88008000 Booting using the fdt blob at 0x88008000 Loading Kernel Image ... OK Loading Device Tree to 8fff4000, end 8ffff588 ... OK Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] ################################## [ 0.000000] ###### MSYS Technologies ###### [ 0.000000] ###### We were here too ###### [ 0.000000] ################################## [ 0.000000] Linux version 4.8.7 ([email protected]) (gcc version 6.1.1 20160711 (Linaro GCC 6.1-2016.08) ) #3 SMP Tue Nov 15 15:27:26 IST 2016 [ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt:Machine model: TI AM335x BeagleBone Black [ 0.000000] cma: Reserved 16 MiB at 0x9e800000 [ 0.000000] Memory policy: Data cache writeback [ 0.000000] CPU: All CPU(s) started in SVC mode. [ 0.000000] AM335X ES2.0 (sgx neon ) [ 0.000000] percpu: Embedded 15 pages/cpu @df913000 s31080 r8192 d22168 u61440 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 129408 [ 0.000000] Kernel command line: root=/dev/mmcblk0p2 rootwait console=ttyO0,115200 [ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes) [ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes) [ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes) [ 0.000000] Memory: 480212K/522240K available (7168K kernel code, 771K rwdata, 2368K rodata, 1024K init, 8121K bss, 25644K reserved, 16384K cma-reserved, ) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xe0800000 - 0xff800000 ( 496 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe0000000 ( 512 MB) [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB) [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB) [ 0.000000] .text : 0xc0008000 - 0xc0800000 (8160 kB) [ 0.000000] .init : 0xc0b00000 - 0xc0c00000 (1024 kB) [ 0.000000] .data : 0xc0c00000 - 0xc0cc0f6c ( 772 kB) [ 0.000000] .bss : 0xc0cc2000 - 0xc14b0570 (8122 kB) [ 0.000000] Running RCU self tests [ 0.000000] Hierarchical RCU implementation. [ 0.000000] RCU lockdep checking is enabled. [ 0.000000] Build-time adjustment of leaf fanout to 32. [ 0.000000] RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1. [ 0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=1 [ 0.000000] NR_IRQS:16 nr_irqs:16 16 [ 0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts [ 0.000000] OMAP clockevent source: timer2 at 24000000 Hz [ 0.000016] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns [ 0.000038] clocksource: timer1: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns [ 0.000081] OMAP clocksource: timer1 at 24000000 Hz [ 0.000552] clocksource_probe: no matching clocksources found [ 0.001435] Console: colour dummy device 80x30 [ 0.001495] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar [ 0.001505] ... MAX_LOCKDEP_SUBCLASSES: 8 [ 0.001513] ... MAX_LOCK_DEPTH: 48 [ 0.001521] ... MAX_LOCKDEP_KEYS: 8191 [ 0.001529] ... CLASSHASH_SIZE: 4096 [ 0.001537] ... MAX_LOCKDEP_ENTRIES: 32768 [ 0.001545] ... MAX_LOCKDEP_CHAINS: 65536 [ 0.001552] ... CHAINHASH_SIZE: 32768 [ 0.001560] memory used by lock dependency info: 5167 kB [ 0.001568] per task-struct memory footprint: 1536 bytes [ 0.001601] Calibrating delay loop... 996.14 BogoMIPS (lpj=4980736) [ 0.078741] pid_max: default: 32768 minimum: 301 [ 0.079192] Security Framework initialized [ 0.079334] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.079347] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.082691] CPU: Testing write buffer coherency: ok [ 0.084154] CPU0: thread -1, cpu 0, socket -1, mpidr 0 [ 0.084230] Setting up static identity map for 0x80100000 - 0x80100070 [ 0.088466] Brought up 1 CPUs [ 0.088492] SMP: Total of 1 processors activated (996.14 BogoMIPS). [ 0.088502] CPU: All CPU(s) started in SVC mode. [ 0.092409] devtmpfs: initialized [ 0.129785] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3 [ 0.130677] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns [ 0.132282] pinctrl core: initialized pinctrl subsystem [ 0.137079] NET: Registered protocol family 16 [ 0.143206] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 0.188334] omap_hwmod: debugss: _wait_target_disable failed [ 0.242397] cpuidle: using governor menu [ 0.255562] OMAP GPIO hardware version 0.1 [ 0.280850] No ATAGs? [ 0.280877] hw-breakpoint: debug architecture 0x4 unsupported. [ 0.281102] omap4_sram_init:Unable to allocate sram needed to handle errata I688 [ 0.281118] omap4_sram_init:Unable to get sram pool needed to handle errata I688 [ 0.326561] edma 49000000.edma: TI EDMA DMA engine driver [ 0.331170] SCSI subsystem initialized [ 0.332881] omap_i2c 44e0b000.i2c: could not find pctldev for node /ocp/[email protected]/[email protected]/[email protected]/pinmux_i2c0_pins, deferring probe [ 0.332998] omap_i2c 4819c000.i2c: could not find pctldev for node /ocp/[email protected]/[email protected]/[email protected]/pinmux_i2c2_pins, deferring probe [ 0.333257] pps_core: LinuxPPS API ver. 1 registered [ 0.333270] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <[email protected]> [ 0.333319] PTP clock support registered [ 0.337569] clocksource: Switched to clocksource timer1 [ 0.438537] VFS: Disk quotas dquot_6.6.0 [ 0.438724] VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) [ 0.470052] NET: Registered protocol family 2 [ 0.472005] TCP established hash table entries: 4096 (order: 2, 16384 bytes) [ 0.472107] TCP bind hash table entries: 4096 (order: 5, 147456 bytes) [ 0.473276] TCP: Hash tables configured (established 4096 bind 4096) [ 0.473477] UDP hash table entries: 256 (order: 2, 20480 bytes) [ 0.473648] UDP-Lite hash table entries: 256 (order: 2, 20480 bytes) [ 0.474451] NET: Registered protocol family 1 [ 0.476406] RPC: Registered named UNIX socket transport module. [ 0.476433] RPC: Registered udp transport module. [ 0.476444] RPC: Registered tcp transport module. [ 0.476454] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.479729] hw perfevents: enabled with armv7_cortex_a8 PMU driver, 5 counters available [ 0.483994] futex hash table entries: 256 (order: 2, 16384 bytes) [ 0.484217] audit: initializing netlink subsys (disabled) [ 0.484459] audit: type=2000 audit(0.470:1): initialized [ 0.488422] workingset: timestamp_bits=14 max_order=17 bucket_order=3 [ 0.491038] NFS: Registering the id_resolver key type [ 0.491368] Key type id_resolver registered [ 0.491383] Key type id_legacy registered [ 0.491534] jffs2: version 2.2. (NAND) (SUMMARY) �© 2001-2006 Red Hat, Inc. [ 0.496681] io scheduler noop registered [ 0.496707] io scheduler deadline registered [ 0.496824] io scheduler cfq registered (default) [ 0.499185] pinctrl-single 44e10800.pinmux: 142 pins at pa f9e10800 size 568 [ 0.501857] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled [ 0.507841] omap_uart 44e09000.serial: no wakeirq for uart0 [ 0.508472] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 158, base_baud = 3000000) is a OMAP UART0 [ 1.218200] console [ttyO0] enabled [ 1.261748] brd: module loaded [ 1.288730] loop: module loaded [ 1.294385] mtdoops: mtd device (mtddev=name/number) must be supplied [ 1.304075] libphy: Fixed MDIO Bus: probed [ 1.377622] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6 [ 1.384001] davinci_mdio 4a101000.mdio: detected phy mask fffffffe [ 1.394381] libphy: 4a101000.mdio: probed [ 1.398751] davinci_mdio 4a101000.mdio: phy: device 4a101000.mdio:00, driver SMSC LAN8710/LAN8720 [ 1.409691] cpsw 4a100000.ethernet: Detected MACID = c8:a0:30:af:7e:3d [ 1.421534] mousedev: PS/2 mouse device common for all mice [ 1.427370] i2c /dev entries driver [ 1.433707] omap_hsmmc 48060000.mmc: Got CD GPIO [ 1.558869] ledtrig-cpu: registered to indicate activity on CPUs [ 1.566706] oprofile: using arm/armv7 [ 1.571341] Initializing XFRM netlink socket [ 1.576148] NET: Registered protocol family 10 [ 1.587785] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver [ 1.596392] NET: Registered protocol family 17 [ 1.601280] NET: Registered protocol family 15 [ 1.606285] Key type dns_resolver registered [ 1.610982] omap_voltage_late_init: Voltage driver support not added [ 1.617682] sr_dev_init: No voltage domain specified for smartreflex0. Cannot initialize [ 1.626120] sr_dev_init: No voltage domain specified for smartreflex1. Cannot initialize [ 1.635272] ThumbEE CPU extension supported. [ 1.639836] Registering SWP/SWPB emulation handler [ 1.644846] SmartReflex Class3 initialized [ 1.686505] mmc0: host does not support reading read-only switch, assuming write-enable [ 1.699452] mmc0: new high speed SDHC card at address aaaa [ 1.709476] mmcblk0: mmc0:aaaa SL08G 7.40 GiB [ 1.718495] random: fast init done [ 1.723267] mmc1: new high speed MMC card at address 0001 [ 1.733401] mmcblk0: p1 p2 [ 1.740069] mmcblk1: mmc1:0001 MMC02G 1.79 GiB [ 1.751587] mmcblk1boot0: mmc1:0001 MMC02G partition 1 1.00 MiB [ 1.759861] mmcblk1boot1: mmc1:0001 MMC02G partition 2 1.00 MiB [ 1.770808] mmcblk1: p1 p2 [ 1.785471] tps65217 0-0024: TPS65217 ID 0xe version 1.2 [ 1.792114] omap_i2c 44e0b000.i2c: bus 0 rev0.11 at 400 kHz [ 1.802517] omap_i2c 4819c000.i2c: bus 2 rev0.11 at 100 kHz [ 1.810044] hctosys: unable to open rtc device (rtc0) [ 1.815338] sr_init: No PMIC hook to init smartreflex [ 1.820944] sr_init: platform driver register failed for SR [ 1.849865] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities [ 1.863870] EXT4-fs (mmcblk0p2): INFO: recovery required on readonly filesystem [ 1.871676] EXT4-fs (mmcblk0p2): write access will be enabled during recovery [ 1.890566] EXT4-fs (mmcblk0p2): recovery complete [ 1.900088] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null) [ 1.908821] VFS: Mounted root (ext4 filesystem) readonly on device 179:2. [ 1.918129] devtmpfs: error mounting -2 [ 1.924181] Freeing unused kernel memory: 1024K (c0b00000 - c0c00000) [ 1.931942] Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance. [ 1.945847] ---[ end Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
It took just two seconds to boot the kernel.
We shall fix this in the next blog and get a complete working embedded Linux machine with the tools we need. The panic is because the kernel is not able to find “init” binary and hand over control to it.[/vc_column_text]