In this post, I will go over how to create a custom Linux image for the Intel Edison using the Yocto Project Edison source code release 2.1.
Apparently, it’s been almost exactly a year since I originally posted how to create a custom Linux kernel. Weird.
Well, since that time, I’ve had some people ask about updating that tutorial, as a few steps no longer apply and the whole thing is out of date. It seems that the Yocto Project also grows and changes over the months.
I created this tutorial with the help of the Yocto Project Getting Started Guide, the Intel Edison Board Support Package, and this thread on the Intel forums.
A few notes before we get started:
- All of these steps are performed on a Linux host machine. I recommend Ubuntu (or another Debian distribution), as I use apt-get liberally.
- You will need at least 50 GB of free hard drive space. The Yocto Project can be quite large.
- The hard drive should be a Linux partition (e.g. Ext4). Trying to execute some of the scripts from an NTFS drive proved difficult.
Download
Navigate to the Intel Edison Downloads page and download Sources – Linux Source Files for the latest Edison firmware release.
Open a console and install some tools:
sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat libsdl1.2-dev
If this is your first time using git, you will want to configure it:
git config –-global user.email “you@example.com” git config –-global user.name “Your Name”
“you@example.com” and “Your Name” are your email and name. Ideally, these would be the email and name you used for something like GitHub.
Perform Initial Build
Navigate to your Downloads directory (or wherever you downloaded the Edison source zip file):
cd Downloads
Unzip and navigate to the Edison source directory:
tar xvf edison-src.tgz cd edison-src/
Run the setup script to download the git repository:
mkdir bitbake_download_dir mkdir bitbake_sstate_dir ./meta-intel-edison/setup.sh --dl_dir=bitbake_download_dir --sstate_dir=bitbake_sstate_dir
Configure our build environment:
cd out/linux64/ source poky/oe-init-build-env
You will automatically be placed in the edison-src/out/linux64/build directory. From there, run bitbake to create an initial Edison image:
bitbake edison-image
This will take some time (potentially hours), as it needs to compile the whole kernel. Subsequent builds will go much faster.
Configure and Create a New Kernel
Make sure you are in the edison-src/out/linux64/build directory, which you should be if you just ran bitbake from the previous step. Open menuconfig:
bitbake virtual/kernel -c menuconfig
From here, you can choose which kernel options you want to include in the build. Read more about menuconfig here. When you are done, save and exit menuconfig. Copy the configuration file to the Edison build directoy:
cp tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux-edison-standard-build/.config ../../../meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/files/defconfig
You can open up the new defconfig file if you want to verify your kernel features. After that, run bitbake again to create the new image:
bitbake edison-image
Finally, run the post-build script (with the build directory as a parameter) to generate the toFlash/ directory:
cd ../../../meta-intel-edison/utils/flash/ ./postBuild.sh ../../../out/linux64/build
Navigate to the toFlash/directory:
cd ../../../out/linux64/build/toFlash/
Flash your Edison
If you want to flash your Edison with a new image, you can plug it into the USB port(s) and run:
sudo ./flashall.sh
This will flash your Edison with your new image! If you want to keep your user data, run the command with the keep-data option:
sudo ./flashall.sh --keep-data
Modify the Edison Kernel
If you want to try and loading in new kernel modules in your existing Edison image, you will need to mount the newly created Edison image on your host machine, extract the modules, and send them to your Edison. This might be risky. I make no promises.
The cool thing about this method is that you can add modules to other versions of Linux for the Edison, like Debian and its unofficial Edison image, Ubilinux.
Plug in your Edison, configure it on your network, and find it’s IP address. You will need it to copy files using scp.
Find the image file edison-image-edison.hddimg in the toFlash/ directory and mount it:
sudo mount edison-image-edison.hddimg /mnt
Copy the 4 files found within to your Edison’s /boot directory (where XXX.XXX.XXX.XXX is your Edison’s IP address, e.g. 192.168.1.5):
scp /mnt/* root@XXX.XXX.XXX.XXX:/boot/
Unmount the Edison image:
sudo umount /mnt
SSH into your Edison:
ssh root@XXX.XXX.XXX.XXX
Remove the old Edison kernel modules and exit SSH:
rm -rf /lib/modules/3.10.17-poky-edison-ww42+ exit
Copy the new modules over to the Edison:
sudo mount edison-image-edison.ext4 /mnt scp -r /mnt/lib/modules/* root@XXX.XXX.XXX.XXX:/lib/modules/
SSH into your Edison to reboot it:
ssh root@XXX.XXX.XXX.XXX reboot
This will kick you out of SSH. Wait a few minutes and then SSH back in:
ssh root@XXX.XXX.XXX.XXX
Once logged in to your Edison, you can use modprobe to enable your new module:
modprobe <MODULE_NAME>
And that’s it! You can check that the module got loaded with:
ls /sys/module/ | grep <MODULE_NAME>
You might notice that you need to run modprobe every time you boot. To perform this step automatically, we can create a configure script that gets run at boot. Make sure you are still logged into your Edison and make a file in /etc/modprobe.d/
sudo nano /etc/modprobe.d/<MODULE_NAME>.conf
In that file, on a single line at the top, enter the command:
modprobe <MODULE_NAME>
Save and exit (‘Ctrl-x’ and ‘y’ in nano). Reboot, and your module should be automatically loaded!
Hi,
Thanks for sharing this, it was very helpful. And I have a question, if I want to create a custom Image for Ubilinux to flash Edison as this https://learn.sparkfun.com/tutorials/loading-debian-ubilinux-on-the-edison. What will be the procedure to do that? I managed to boot Ubilinux but my motive is to boot the Edison as much as faster without any prompts, Since im new to this I dont have much idea about this. Any help would be much appreciated. Thanks
I do not think Emutex Labs posts their source code for Ubilinux, which means there is no good starting point for creating a custom Ubilinux image. You will need to create a Debian image using the Yocto Project. Here is a good start: http://events.linuxfoundation.org/sites/events/files/slides/LinuxCon2015_meta-debian_r7.pdf
is this instruction still valid today(4/24/2016)? because the Sources – Linux Source Files no longer exists, and even if I dowloaded the souce file from “Release 3.0 Yocto* complete image”, the step : “./meta-intel-edison/setup.sh –dl_dir=bitbake_download_dir –sstate_dir=bitbake_sstate_dir” no longer works for i get the output message :./meta-intel-edison/setup.sh no such file or directory.
With the release of the 3.0 image, I doubt that these instructions are still valid. Once I get some free time to play with the new release, I plan to write an updated guide to building a custom image for 3.0.
I think currently for Yocto 3.0 is not possible to build from source yet based on 6th May 2016. It seems that the sources for the Yocto 3.0 build is missing or having some issues. I think we have to wait for Intel to release the Linux Sources for Yocto 3.0 till then we develop on the previous version.
You can keep up to date on this issue here:
https://communities.intel.com/thread/100735?tstart=0
The last post was on 5th May 2016.
Good to know, thanks!
Building a custom image for release 3.0 is possible and only requires very slight modification to the instructions above.
The build recipe for MQTT needs to have it’s repository uri changed.
and the build recipe for linux-externalsrc needs to be changed to allow custom defconfig files to be used.
Other than that it goes off without a hitch!
Awesome! Thanks 🙂
hi i am getting some problems using the sudo ./flashall.sh
its displaying an error message like:
——————————————————————————-
lease plug and reboot the board
Timed out while waiting for dfu device 8087:0a99
DEBUG: lsusb
Bus 001 Device 007: ID 8087:0a9e Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 008: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Bus 002 Device 006: ID 80ee:0021 VirtualBox USB Tablet
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
DEBUG: dfu-util -l
dfu-util 0.5
(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.
(C) 2010-2011 Tormod Volden (DfuSe support)
This program is Free Software and has ABSOLUTELY NO WARRANTY
dfu-util does currently only support DFU version 1.0
Did you plug and reboot your board?
If yes, please try a recovery by calling this script with the –recovery option
———————————————————————-
how do i solve this
Which board are you using (Base Block, Mini Breakout, Arduino Breakout)? If it is the Mini or Arduino Breakout, I found that you need to plug in both USB ports.
Additionally, you may want to try running the script first, and then plug in the board when it says “please plug and reboot the board.”
Hey,
Thanks for the great tutorial! I’m having an issue with the bitbake command…I got as far as copying over the new config file to defconfig, but then when I tried to create the new image (“bitbake edison-image”), my computer can’t find bitbake (“bitbake: command not found”).
Any idea what the issue might be?
The
command should work after running the
command. Here is a reference guide to Yocto, which should cover bitbake.
The ./flashall.sh scipt should be executed as sudo, otherwise the edison wont get flashed though the script report flashing success,
This is a huge bug, wasted my huge time
Thanks for letting me know, the command has been updated.
Thanks for your detail step by step tutorial. It is very helpful.
i can build a 32 bit version.
Now i am trying build 64 bit kernel, but got some issues:
After run “bitbake virtual/kernel -c menuconfig”
i choose [*]64 bit kernel and save
then copy the configuration file to the Edison build directoy
then run “bitbake edison-image” again, but i get an error.
i find the log under /out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/temp/log.do_compile.6126 :
————————————————————————————-
DEBUG: Executing shell function do_compile
NOTE: make -j 4 bzImage CC=i586-poky-linux-gcc LD=i586-poky-linux-ld.bfd
GEN /home/marcus/src/edison/edison-src/out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux-edison-standard-build/Makefile
scripts/kconfig/conf –silentoldconfig Kconfig
SYSHDR arch/x86/syscalls/../include/generated/uapi/asm/unistd_32.h
SYSHDR arch/x86/syscalls/../include/generated/uapi/asm/unistd_64.h
SYSHDR arch/x86/syscalls/../include/generated/uapi/asm/unistd_x32.h
SYSTBL arch/x86/syscalls/../include/generated/asm/syscalls_32.h
SYSHDR arch/x86/syscalls/../include/generated/asm/unistd_32_ia32.h
SYSHDR arch/x86/syscalls/../include/generated/asm/unistd_64_x32.h
SYSTBL arch/x86/syscalls/../include/generated/asm/syscalls_64.h
GEN /home/marcus/src/edison/edison-src/out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux-edison-standard-build/Makefile
CHK include/generated/uapi/linux/version.h
CHK include/generated/utsrelease.h
CC scripts/mod/empty.o
HOSTCC scripts/selinux/genheaders/genheaders
/home/marcus/src/edison/edison-src/out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/scripts/mod/empty.c:1:0: error: code model ‘kernel’ not supported in the 32 bit mode
/* empty file to figure out endianness / word size */
^
/home/marcus/src/edison/edison-src/out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/scripts/mod/empty.c:1:0: sorry, unimplemented: 64-bit mode not compiled in
make[3]: *** [scripts/mod/empty.o] Error 1
make[2]: *** [scripts/mod] Error 2
make[2]: *** Waiting for unfinished jobs….
HOSTCC scripts/selinux/mdp/mdp
make[1]: *** [scripts] Error 2
make[1]: *** Waiting for unfinished jobs….
make: *** [sub-make] Error 2
ERROR: oe_runmake failed
WARNING: exit code 1 from a shell command.
ERROR: Function failed: do_compile (log file is located at /home/marcus/src/edison/edison-src/out/linux64/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/temp/log.do_compile.6126)
————————————————————————————————–
Do you have an idea about the issues ? Thanks~
The Edison has a 32-bit Quark processor, so I highly doubt the 64-bit kernel will run even if you manage to compile it. I suspect the part that says “error: code model ‘kernel’ not supported in the 32 bit mode” refers to the fact that the kernel simply won’t compile for a 32-bit processor.
Is Edison has 2 processor one 64 bit and one 32 bit??
22nm Intel® Intel® Atom™ x86_64 SoC at 500MHz with HyperThreading + 32-bit Intel® Quark™
Below link state it has a 64 bit processor
https://edison.internet-share.com/wiki/Using_a_vanilla_Linux_kernel_with_Intel_Edison
Hmm…you’re right, the Atom processor (Z34XX) is listed as a 64- bit core. I always thought it was 32 bit. However, it seems that there is some confusion even among Intel staff as to why a 64-bit kernel will not work. I must refer you to this article: https://communities.intel.com/message/264501#264501
Maybe just like you said there is a 32 bit processor so 64 bit kernel wouldn’t work.
Thanks for your help and the great article~
It has two 64-bit cores and separate Quark core which is i486+.
Thanks! Helped a lot your guide + http://bovs.org/post/168/Building-Yocto-linux-for-Intel-Edison-with-3G-USB-modems-support
Glad it helped! A 3G modem would be cool for the Edison.
How to run these commands on Windows. I use Windows host machine. Can you please give the codes for Windows version?
I have not used Yocto on Windows, so I cannot tell you how it’s done. You’ll either need Windows Bash or something like MinGW to make it work. Yocto supposedly supports Windows and macOS, so you’ll want to read the Yocto Manual to see how to get started.