文章目录
- Summary
- Run a QT Demo on QEMU
- Convert the kernel image to uImage format
- QEMU Networking
- Booting via TFTP
- Reference
Summary
Tested QEMU and Graphic application on Embedded Linux S3C2440.
QEMU is open-source software, can be run on Windows and Linux host, it is software based emulator and instruction set simulator to be used to simulate the embedded processors. QEMU supports the emulation of several target architectures like ARM, PowerPC, x86.
QT for embedded linux is a C++ framework for GUI and application development for embedded device. It can be run on a variety of processors included Embedded Linux. QT provides the standard QT API for embedded devices with a lightweight window system. QT is meant for cross-platform development, the source code can be compiled on x86 platform, run and debug it on the host PC, the same source code for your target platform can be compiled for the target architecture. The application can also be debugged through remote debugging tools, and only the QT-Embedded is installed.
Run a QT Demo on QEMU
All the test will be running on the host and on the instruction set simulator.
The QEMU instruction set simulator qemu-system-arm
is installed in /home/iot/qemu-mini2440/qemu/arm-softmmu
. The source code is in /home/iot/qemu-mini2440/qemu
, this version is dedicated for S3C2440 board. It executes the bootloader u-boot first.
[root@localhost arm-softmmu]# pwd
/home/iot/qemu-mini2440/qemu/arm-softmmu
[root@localhost arm-softmmu]# ls
arm_boot.d cbus.d exec.d ide.d mini2440.d omap2.d op_helper.d pl031.d pxa2xx_gpio.o realview_gic.o s3c24xx_udc.d syborg_interrupt.d tosa.d vga.d
arm_boot.o cbus.o exec.o ide.o mini2440.o omap2.o op_helper.o pl031.o pxa2xx_keypad.d realview.o s3c24xx_udc.o syborg_interrupt.o tosa.o vga.o
arm-dis.d config.h fpu integratorcp.d monitor.d omap_clk.d osdep.d pl050.d pxa2xx_keypad.o rtl8139.d serial.d syborg_keyboard.d translate-all.d virtio-balloon.d
arm-dis.o config.mak framebuffer.d integratorcp.o monitor.o omap_clk.o osdep.o pl050.o pxa2xx_lcd.d rtl8139.o serial.o syborg_keyboard.o translate-all.o virtio-balloon.o
arm_pic.d cpu-exec.d framebuffer.o isa_mmio.d mpcore.d omap_dma.d palm.d pl061.d pxa2xx_lcd.o s3c2410.d smc91c111.d syborg.o translate.d virtio-blk.d
arm_pic.o cpu-exec.o gdbstub.d isa_mmio.o mpcore.o omap_dma.o palm.o pl061.o pxa2xx_mmci.d s3c2410_nand.d smc91c111.o syborg_pointer.d translate.o virtio-blk.o
arm-semi.d disas.d gdbstub.o iwmmxt_helper.d mst_fpga.d omap_dss.d pci.d pl080.d pxa2xx_mmci.o s3c2410_nand.o soc_dma.d syborg_pointer.o tsc210x.d virtio-console.d
arm-semi.o disas.o gdbstub-xml.c iwmmxt_helper.o mst_fpga.o omap_dss.o pci.o pl080.o pxa2xx.o s3c2410.o soc_dma.o syborg_rtc.d tsc210x.o virtio-console.o
arm_sysctl.d dm9000.d gdbstub-xml.d libqemu.a musicpal.d omap_i2c.d pcnet.d pl110.d pxa2xx_pcmcia.d s3c2440_nand.d spitz.d syborg_rtc.o tusb6010.d virtio-net.d
arm_sysctl.o dm9000.o gdbstub-xml.o loader.d musicpal.o omap_i2c.o pcnet.o pl110.o pxa2xx_pcmcia.o s3c2440_nand.o spitz.o syborg_serial.d tusb6010.o virtio-net.o
arm_timer.d e1000.d gumstix.d loader.o ne2000.d omap_lcdc.d pflash_cfi01.d pl181.d pxa2xx_pic.d s3c24xx_gpio.d start-qemu syborg_serial.o usb-musb.d vl.d
arm_timer.o e1000.o gumstix.o lsi53c895a.d ne2000.o omap_lcdc.o pflash_cfi01.o pl181.o pxa2xx_pic.o s3c24xx_gpio.o stellaris.d syborg_timer.d usb-musb.o vl.o
armv7m.d eepro100.d helper.d lsi53c895a.o neon_helper.d omap_mmc.d pflash_cfi02.d pl190.d pxa2xx_timer.d s3c24xx_lcd.d stellaris_enet.d syborg_timer.o usb-ohci.d wdt_i6300esb.d
armv7m_nvic.d eepro100.o helper.o machine.d neon_helper.o omap_mmc.o pflash_cfi02.o pl190.o pxa2xx_timer.o s3c24xx_lcd.o stellaris_enet.o syborg_virtio.d usb-ohci.o wdt_i6300esb.o
armv7m_nvic.o eeprom24c0x.d host-utils.d machine.o nseries.d omap_sx1.d pl011.d pxa2xx.d qemu-options.h s3c24xx_mmci.d stellaris.o syborg_virtio.o versatilepb.d wdt_ib700.d
armv7m.o eeprom24c0x.o host-utils.o mainstone.d nseries.o omap_sx1.o pl011.o pxa2xx_dma.d qemu-system-arm s3c24xx_mmci.o syborg.d tc6393xb.d versatilepb.o wdt_ib700.o
blizzard.d esp.d i386-dis.d mainstone.o omap1.d onenand.d pl022.d pxa2xx_dma.o realview.d s3c24xx_rtc.d syborg_fb.d tc6393xb.o versatile_pci.d zaurus.d
blizzard.o esp.o i386-dis.o Makefile omap1.o onenand.o pl022.o pxa2xx_gpio.d realview_gic.d s3c24xx_rtc.o syborg_fb.o tcg versatile_pci.o zaurus.o
[root@localhost arm-softmmu]#
The uImage kernel-uImage
is in /home/iot/qemu-mini2440/qemu/mini2440/
.
U-boot
for S3C2440 source code is in /home/iot/uboot-mini2440/
.
QT 4.8.1 is installed in /usr/local/qt
. QT demos are installed in /usr/local/qt/demos
.
First run the script mini2440_start.sh
to start QEMU.
[root@localhost qemu]# pwd
/home/iot/qemu-mini2440/qemu
[root@localhost qemu]# ./mini2440/mini2440_start.sh
Starting in ./mini2440
/home/iot/qemu-mini2440/qemu/arm-softmmu/qemu-system-arm -M mini2440 -drive file=./mini2440/mini2440_snapshots.img,snapshot=on -serial stdio -kernel /home/iot/qemu-mini2440/qemu/mini2440/kernel-uImage -mtdblock ./mini2440/mini2440_nand.bin -usb -usbdevice mouse -usbdevice keyboard -show-cursor -net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=no
S3C: CLK=240 HCLK=240 PCLK=240 UCLK=57
QEMU: ee24c08_init
DM9000: INIT QEMU MAC : 52:54:00:12:34:56
QEMU mini2440_reset: loaded default u-boot from NAND
QEMU mini2440_reset: loaded override u-boot (size 39800)
QEMU mini2440_reset: loaded /home/iot/qemu-mini2440/qemu/mini2440/kernel-uImage (size 53ce00)
S3C: CLK=240 HCLK=60 PCLK=30 UCLK=57
S3C: CLK=240 HCLK=60 PCLK=30 UCLK=48
S3C: CLK=405 HCLK=101 PCLK=50 UCLK=48 U-Boot 1.3.2-mini2440 (Apr 23 2013 - 14:35:51) I2C: ready
DRAM: 64 MB
NOR Flash not found. Use hardware switch and 'flinit'
Flash: 0 kB
NAND: Bad block table not found for chip 0
Bad block table not found for chip 0
64 MiB
*** Warning - bad CRC or NAND, using default environmentUSB: S3C2410 USB Deviced
In: serial
Out: serial
Err: serial
MAC: 08:08:11:18:12:27
Hit any key to stop autoboot: 0
MINI2440 #
The script mini2440_start.sh
is as below,
#!/bin/bashbase=$(dirname $0)echo Starting in $basename_nand="$base/mini2440_nand.bin"
name_snapshots="$base/mini2440_snapshots.img"if [ ! -f "$name_nand" ]; thenecho $0 : creating NAND empty image : "$name_nand"dd if=/dev/zero of="$name_nand" bs=528 count=131072
fi
if [ ! -f "$name_snapshots" ]; thenecho $0 : creating empty snapshot image : "$name_snapshots"/home/iot/qemu-mini2440/qemu/qemu-img create "$name_snapshots" 100MB
fi#-usbdevice keyboard
#-show-cursor
#-serial tcp::2222,server
#-serial stdio
#-monitor telnet::5555,server,nowait
cmd="/home/iot/qemu-mini2440/qemu/arm-softmmu/qemu-system-arm \-M mini2440 $* \-drive file=$name_snapshots,snapshot=on \-serial stdio \-kernel /home/iot/qemu-mini2440/qemu/mini2440/kernel-uImage \-mtdblock "$name_nand"-usb -usbdevice mouse -usbdevice keyboard\-show-cursor \-net nic,vlan=0 \-net tap,vlan=0,ifname=tap0,script=no"echo $cmd
$cmd
Kernel-uImage is a precompiled kernel image in uImage format. It contains the executable of the affine
demo and the libraries needed. As above script shows, the kernel
option is -kernel /home/iot/qemu-mini2440/qemu/mini2440/kernel-uImage
, it tells QEMU to load the kernel of the simulated machine S3C2440
in the RAM, after S3C2440 boot up and the Bootloader command prompt appeared, can use help
command to show all u-boot commands, as below shows.
MINI2440 # help
? - alias for 'help'
autoscr - run script from memory
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootm - boot application image from memory
bootp - boot image via network using BootP/TFTP protocol
chpart - change active partition
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
date - get/set/reset date & time
dhcp - invoke DHCP client to obtain IP/boot params
dynenv - dynamically placed (NAND) environment
dynpart - dynamically calculate partition table based on BBT
echo - echo args to console
erase - erase FLASH memory
ext2load- load binary file from a Ext2 filesystem
ext2ls - list files in a directory (default /)
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
flinfo - print FLASH memory information
flinit - Initialize/probe NOR flash memory
fsinfo - print information about filesystems
fsload - load binary file from a filesystem image
go - start application at address 'addr'
help - print online help
icrc32 - checksum calculation
iloop - infinite loop on address range
imd - i2c memory display
iminfo - print header information for application image
imls - list all images found in flash
imm - i2c memory modify (auto-incrementing)
imw - memory write (fill)
imxtract- extract a part of a multi-image
in - read data from an IO port
inm - memory modify (constant address)
iprobe - probe to discover valid I2C chip addresses
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
ls - list files in a directory (default /)
md - memory display
mm - memory modify (auto-incrementing)
mmcinit - init mmc card
mtdparts- define flash/nand partitions
mtest - simple RAM test
mw - memory write (fill)
nand - NAND sub-system
nboot - boot from NAND device
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
out - write datum to IO port
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
rarpboot- boot image via network using RARP/TFTP protocol
reginfo - print register information
reset - Perform RESET of the CPU
run - run commands in an environment variable
s3c24xx - SoC specific commands
saveenv - save environment variables to persistent storage
saves - save S-Record file over serial line
setenv - set environment variables
sleep - delay execution for some time
tftpboot- boot image via network using TFTP protocol
usb - USB sub-system
usbboot - boot from USB device
version - print monitor version
MINI2440 #
Before jump to kernel, we nee do key in Linux command line to set the simulated screen size. U-boot will pass it to kernel.
MINI2440 # setenv bootargs console=ttySAC0,115200 init=/init mini2440=1tb
As above shows, mini2440=1tb
, 1
means the screen is 7’ LCD 800*480, t
means touch screen and b
means back light.
Use command bootm
to jump to kernel, then key in root
to log in.
MINI2440 # bootm
## Booting kernel from Legacy Image at 32000000 ...Image Name: Created: 2019-05-31 6:54:22 UTCImage Type: ARM Linux Kernel Image (uncompressed)Data Size: 5491848 Bytes = 5.2 MBLoad Address: 30008000Entry Point: 30008000Verifying Checksum ... OKLoading Kernel Image ... OK
OKStarting kernel ...Uncompressing Linux... done, booting the kernel.
s3c_timers_write: Bad register 0x40
s3c_uart_write: Bad register 0x2c
Booting Linux on physical CPU 0x0
Linux version 3.8.7-FriendlyARM (root@localhost.localdomain) (gcc version 4.7.2 (Buildroot 2013.02) ) #11 Wed Aug 16 15:51:19 SGT 2017
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: root=/dev/mtdblock3 rootfstype=jffs2 console=ttySAC0,115200
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
__ex_table already sorted, skipping sort
Memory: 64MB = 64MB total
Memory: 52796k/52796k available, 12740k reserved, 0K highmem
Virtual kernel memory layout:vector : 0xffff0000 - 0xffff1000 ( 4 kB)fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)vmalloc : 0xc4800000 - 0xff000000 ( 936 MB)lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)modules : 0xbf000000 - 0xc0000000 ( 16 MB).text : 0xc0008000 - 0xc0427ee4 (4224 kB).init : 0xc0428000 - 0xc0b61a04 (7399 kB).data : 0xc0b62000 - 0xc0b9d988 ( 239 kB).bss : 0xc0b9d988 - 0xc0bd9948 ( 240 kB)
SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:85
irq: clearing subpending status 00000002
sched_clock: 32 bits at 200 Hz, resolution 5000000ns, wraps every 4294967291ms
Console: colour dummy device 80x30
Calibrating delay loop... 67.99 BogoMIPS (lpj=169984)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x30307150 - 0x3030718c
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
MINI2440: Option string mini2440=0tb
MINI2440: 't' ignored, touchscreen not compiled in
MINI2440: LCD [0:240x320] 1:800x480 2:1024x768 3:320x240
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C244X: Clock Support, DVS off
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Linux video capture interface: v2.00
NET: Registered protocol family 2
TCP established hash table entries: 512 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 512 bind 512)
TCP: reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
NetWinder Floating Point Emulator V0.97 (double precision)
jffs2: version 2.2. (NAND) ? 2001-2006 Red Hat, Inc.
msgmni has been set to 103
alg: No test for stdrng (krng)
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
Console: switching to colour frame buffer device 30x20
s3c2410-lcd s3c2410-lcd: fb0: s3c2410fb frame buffer device
s3c2440-uart.0: ttySAC0 at MMIO 0x50000000 (irq = 70) is a S3C2440
console [ttySAC0] enabled
s3c2440-uart.1: ttySAC1 at MMIO 0x50004000 (irq = 73) is a S3C2440
s3c2440-uart.2: ttySAC2 at MMIO 0x50008000 (irq = 76) is a S3C2440
brd: module loaded
loop: module loaded
Loading iSCSI transport class v2.0-870.
s3c24xx-nand s3c2440-nand: Tacls=1, 9ns Twrph0=3 29ns, Twrph1=2 19ns
s3c24xx-nand s3c2440-nand: NAND soft ECC
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit), 64MiB, page size: 512, OOB size: 16
Creating 4 MTD partitions on "nand":
0x000000000000-0x000000040000 : "u-boot"
0x000000040000-0x000000060000 : "u-boot-env"
0x000000060000-0x000000560000 : "kernel"
0x000000560000-0x000004000000 : "root"
dm9000 Ethernet Driver, V1.31
dm9000_probe Set bwscon and bankcon4
eth0: dm9000e at c48bc300,c48be304 IRQ 51 MAC: 08:08:11:18:12:27 (chip)
usbcore: registered new interface driver cdc_ether
usbcore: registered new interface driver rndis_host
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
mousedev: PS/2 mouse device common for all mice
s3c-rtc s3c2410-rtc: rtc disabled, re-enabling
s3c-rtc s3c2410-rtc: rtc core: registered s3c as rtc0
oprofile: no performance counters
oprofile: using timer interrupt.
TCP: cubic registered
Initializing XFRM netlink socket
NET: Registered protocol family 17
Key type dns_resolver registered
console [netcon0] enabled
netconsole: network logging started
s3c-rtc s3c2410-rtc: setting system clock to 2019-06-05 11:21:34 UTC (1559733694)
s3c_uart_write: Bad register 0x2c
Freeing init memory: 7396K
s3c_uart_write: Bad register 0x2c
s3c_uart_write: Bad register 0x2c
starting pid 440, tty '': '/etc/init.d/rcS'
* Mounting /proc...
* Mounting /dev...
* Mounting /sys...
* Mounting /dev/pts...
* Mounting /dev/shm...
* Starting system loggers...
* Creating devices...
* Configuring loopback interface...
* Setting hostname...
eth0 up
dm9000_mii_read: Bad register 0x1b
dm9000 dm9000 eth0: link up, 10Mbps, half-duplex, lpa 0x0400
s3c_uart_write: Bad register 0x2c
starting pid 456, tty '': '/usr/sbin/telnetd -l /bin/login'
s3c_uart_write: Bad register 0x2c
starting pid 457, tty '': '-/bin/login'
mini2440 login: root
-sh: can't access tty; job control turned off
[root@mini2440 /root]#
Change to directory /usr/bin
, run a script qtsetting.sh
to set environment variables for QT.
[root@mini2440 /root]# cd /usr/bin/
[root@mini2440 bin]# ls
affine less opreport
awk logger oprofiled
cut logname pstree
dirname lsusb pwdx
env op-check-perfevents qtsetting.sh
expr opannotate sv
fold oparchive tftp
free opcontrol time
ftpget openvt top
ftpput operf tr
gdbserver opgprof uptime
id ophelp wget
install opimport which
ldd opjitconv
[root@mini2440 bin]# cat qtsetting.sh
#!/bin/sh
export QWS_DISPLAY=LinuxFB:mmWidth=95:mmHeight=155
export QWS_KEYBOARD=USB:/dev/input/event0
export QWS_MOUSE_PROTO=IntelliMouse:/dev/input/mice
export QWS_SIZE=800*480
[root@mini2440 bin]# source qtsetting.sh
[root@mini2440 bin]#
The little penguin appears on the emulated LCD.
Run the affine
demo at the back ground,
[root@mini2440 bin]# ./affine -qws &
[root@mini2440 bin]#
On the simulated screen of S3C2440, the animation of affine is as below, you can use the mouse on the screen to click the buttons and bars. To exit the mouse from the screen, press Ctrl+Alt. To terminate the QEMU, press Ctrl + C.
The affine
demo is in the QT demo directory on the host,
[root@localhost affine]# ls
affine affine.pro affine.qrc bg1.jpg main.cpp xform.cpp xform.h xform.html
[root@localhost affine]# pwd
/usr/local/qt/demos/affine
[root@localhost affine]#
It was compiled into zImage
then convert into kernel-uImage
through shell script create_rootfs_bash.sh
,
cp -P /usr/local/qt/lib/libQtGui* usr/local/qt/lib
cp -P /usr/local/qt/lib/libQtNetwork* usr/local/qt/lib
cp -P /usr/local/qt/lib/libQtCore* usr/local/qt/lib
cp -rdP /usr/local/qt/lib/fonts usr/local/qt/lib
cp /usr/local/qt/demos/affine/affine usr/bin
Convert the kernel image to uImage format
Use the script generateKerneluImage.sh
to convert the kernel image to uImage format and put into /home/iot/qemu-mini2440/qemu/mini2440/
,
#!/bin/sh
./mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d mini2440/linux-3.8.7/arch/arm/boot/zImage qemu-mini2440/qemu/mini2440/kernel-uImage
The script converts the file mini2440/linux-3.8.7/arch/arm/boot/zImage
to kernel-uImage, as below help information shows, the parameter -A
specifies architecture. -O
specifies OS. -a
specifies load address. -e
specifies execute address. -d
specified the input file.
[root@localhost]# ./mkimage -h
Usage: ./mkimage -l image-l ==> list image header information./mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image-A ==> set architecture to 'arch'-O ==> set operating system to 'os'-T ==> set image type to 'type'-C ==> set compression type 'comp'-a ==> set load address to 'addr' (hex)-e ==> set entry point to 'ep' (hex)-n ==> set image name to 'name'-d ==> use image data from 'datafile'-x ==> set XIP (execute in place)./mkimage [-D dtc_options] -f fit-image.its fit-image
QEMU Networking
QEMU allows the guest OS to communicate with the host OS via Ethernet. We need to create a bridge between them. The script qemu-ifup
is used to achieve this. The content of qemu-ifup
is as below. The script takes two parameters. The first parameter is the name of tap device, e.g. tap0. The second parameter is the device name of the Ethernet interface, such as eth0, p3p1 or em1, etc.
#!/bin/sh
#
# script to bring up the tun device in QEMU in bridged mode
# first parameter is name of tap device (e.g. tap0)
#
# some constants specific to the local host - change to suit your host
#
ETH0IP=192.168.0.10
GATEWAY=192.168.0.1
BROADCAST=192.168.0.255 #determined by subnet range used
#
# First take eth0 down, then bring it up with IP 0.0.0.0
#
#sudo /sbin/ifdown eth0
sudo /sbin/ifdown $2
#
#sudo /sbin/ifconfig eth0 0.0.0.0 promisc up
sudo /sbin/ifconfig $2 0.0.0.0 promisc up
#
# Bring up the tap device (name specified as first argument, by QEMU)
#
sudo /usr/sbin/openvpn --mktun --dev $1 --user `id -un`
sudo /sbin/ifconfig $1 0.0.0.0 promisc up
#
# create the bridge between eth0 and the tap device
#
sudo /usr/sbin/brctl addbr br0
#sudo /usr/sbin/brctl addif br0 eth0
sudo /usr/sbin/brctl addif br0 $2
sudo /usr/sbin/brctl addif br0 $1
#
# only a single bridge so loops are not possible, turn off spanning tree protocol
#
sudo /usr/sbin/brctl stp br0 off
#
# Bring up the bridge with ETH0IP and add the default route if you are using static IP
#
/sbin/ifconfig br0 $ETH0IP netmask 255.255.255.0 broadcast $BROADCAST
/sbin/route add default gw $GATEWAY
#
#
# stop firewall, if you dont you cannot run virtual OS for public services as outside can't connect to it.
#
systemctl stop firewalld.service
The current Ethernet interface configuration is as below, we will use Ethernet interface eth0 as the bridge setting.
[root@localhost ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255inet6 fe80::a00:27ff:fefc:6596 prefixlen 64 scopeid 0x20<link>ether 08:00:27:fc:65:96 txqueuelen 1000 (Ethernet)RX packets 31 bytes 3339 (3.2 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 39 bytes 3862 (3.7 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.18.101 netmask 255.255.255.0 broadcast 192.168.18.255inet6 fe80::a00:27ff:fece:b1b2 prefixlen 64 scopeid 0x20<link>ether 08:00:27:ce:b1:b2 txqueuelen 1000 (Ethernet)RX packets 1718 bytes 166886 (162.9 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 1878 bytes 297301 (290.3 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255inet6 fe80::a00:27ff:fe5e:4788 prefixlen 64 scopeid 0x20<link>ether 08:00:27:5e:47:88 txqueuelen 1000 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 7 bytes 578 (578.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 16436inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 0 (Local Loopback)RX packets 22 bytes 1690 (1.6 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 22 bytes 1690 (1.6 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255ether c6:fb:dc:85:32:8f txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@localhost ~]#
Use the above script qemu-ifup
to setup the bridge, the second parameter is the host Ethernet port device name.
[root@localhost ~]# ./qemu-ifup tap0 eth0
Wed Jun 5 23:07:30 2019 TUN/TAP device tap0 opened
Wed Jun 5 23:07:30 2019 Persist state set to: ON
[root@localhost ~]#
Check the result as below,
[root@localhost ~]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.0.10 netmask 255.255.255.0 broadcast 192.168.0.255inet6 fe80::a00:27ff:fefc:6596 prefixlen 64 scopeid 0x20<link>ether 08:00:27:fc:65:96 txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 6 bytes 468 (468.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500inet6 fe80::a00:27ff:fefc:6596 prefixlen 64 scopeid 0x20<link>ether 08:00:27:fc:65:96 txqueuelen 1000 (Ethernet)RX packets 31 bytes 3339 (3.2 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 45 bytes 4330 (4.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.18.101 netmask 255.255.255.0 broadcast 192.168.18.255inet6 fe80::a00:27ff:fece:b1b2 prefixlen 64 scopeid 0x20<link>ether 08:00:27:ce:b1:b2 txqueuelen 1000 (Ethernet)RX packets 1723 bytes 168429 (164.4 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 1882 bytes 298105 (291.1 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255inet6 fe80::a00:27ff:fe5e:4788 prefixlen 64 scopeid 0x20<link>ether 08:00:27:5e:47:88 txqueuelen 1000 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 7 bytes 578 (578.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 16436inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 0 (Local Loopback)RX packets 22 bytes 1690 (1.6 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 22 bytes 1690 (1.6 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0tap0: flags=4355<UP,BROADCAST,PROMISC,MULTICAST> mtu 1500ether ea:48:eb:db:58:53 txqueuelen 100 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255ether c6:fb:dc:85:32:8f txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@localhost ~]#
Test the connection by ping the target simulated S3C2440.
First startup,
[root@localhost qemu]# ./mini2440/mini2440_start.sh
...(omit..load the kernel image into RAM of the emulated S3C2440 board)
MINI2440 # setenv bootargs console=ttySAC0,115200 init=/init mini2440=1tb
MINI2440 # bootm
...(omit..from u-boot jump to the kernel image in RAM)
mini2440 login: root
-sh: can't access tty; job control turned off
[root@mini2440 /root]# ifconfig
eth0 Link encap:Ethernet HWaddr 08:08:11:18:12:27 inet addr:192.168.0.11 Bcast:192.168.0.255 Mask:255.255.255.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)Interrupt:51 Base address:0x2300 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0UP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
From host ping to simulated S3C2440 linux, it was failed,
[root@localhost ~]# ping 192.168.0.11
PING 192.168.0.11 (192.168.0.11) 56(84) bytes of data.
From 192.168.0.1 icmp_seq=1 Destination Host Unreachable
Noticed that the eth2 also has 192.168.0.1 address, it is the same network segment as the bridge, it may confuse the host network connection, ifdown
eth2 and ping again, it is successful now after the change.
[root@localhost ~]# ifdown eth2
[root@localhost ~]# ping 192.168.0.11
PING 192.168.0.11 (192.168.0.11) 56(84) bytes of data.
64 bytes from 192.168.0.11: icmp_seq=1 ttl=64 time=7.56 ms
64 bytes from 192.168.0.11: icmp_seq=2 ttl=64 time=0.296 ms
^C
--- 192.168.0.11 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.296/3.929/7.563/3.634 ms
[root@localhost ~]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.0.10 netmask 255.255.255.0 broadcast 192.168.0.255inet6 fe80::a00:27ff:fefc:6596 prefixlen 64 scopeid 0x20<link>ether 08:00:27:fc:65:96 txqueuelen 0 (Ethernet)RX packets 4 bytes 224 (224.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 10 bytes 748 (748.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500inet6 fe80::a00:27ff:fefc:6596 prefixlen 64 scopeid 0x20<link>ether 08:00:27:fc:65:96 txqueuelen 1000 (Ethernet)RX packets 31 bytes 3339 (3.2 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 46 bytes 4390 (4.2 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.18.101 netmask 255.255.255.0 broadcast 192.168.18.255inet6 fe80::a00:27ff:fece:b1b2 prefixlen 64 scopeid 0x20<link>ether 08:00:27:ce:b1:b2 txqueuelen 1000 (Ethernet)RX packets 1726 bytes 169322 (165.3 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 1884 bytes 298507 (291.5 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet6 fe80::a00:27ff:fe5e:4788 prefixlen 64 scopeid 0x20<link>ether 08:00:27:5e:47:88 txqueuelen 1000 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 13 bytes 938 (938.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 16436inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 0 (Local Loopback)RX packets 29 bytes 2474 (2.4 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 29 bytes 2474 (2.4 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0tap0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500inet6 fe80::e848:ebff:fedb:5853 prefixlen 64 scopeid 0x20<link>ether ea:48:eb:db:58:53 txqueuelen 100 (Ethernet)RX packets 4 bytes 280 (280.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 10 bytes 748 (748.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255ether c6:fb:dc:85:32:8f txqueuelen 0 (Ethernet)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[root@localhost ~]#
Now you can try NFS, tftp and telnet operations.
Test on Telnet,
[root@localhost ~]# telnet 192.168.0.11
Trying 192.168.0.11...
Connected to 192.168.0.11.
Escape character is '^]'.mini2440 login: root
[root@mini2440 /root]#
Test on TFTP:
[root@mini2440 /root]# tftp -g -r thread_demo_RR_max_min 192.168.0.10
thread_demo_RR_max_m 100% |********************************************************************************************************************************************************************************************| 10576 0:00:00 ETA
[root@mini2440 /root]# ls
thread_demo_RR_max_min
[root@mini2440 /root]#
Test on NFS,
[root@mini2440 /root]# mount -t nfs 192.168.0.10:/home /mnt -otcp, -o nolock
[root@mini2440 /root]# mount
rootfs on / type rootfs (rw)
/proc on /proc type proc (rw,relatime)
mdev on /dev type tmpfs (rw,relatime)
none on /sys type sysfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
none on /dev/shm type tmpfs (rw,relatime)
192.168.0.10:/home on /mnt type nfs (rw,relatime,vers=3,rsize=131072,wsize=131072,namlen=255,hard,nolock,proto=tcp,port=2049,timeo=70,retrans=3,sec=sys,local_lock=all,addr=192.168.0.10)
[root@mini2440 /root]#
You can also do the gdb debugging, kernel debugging and profiling by using QEMU.
A script qemu-ifdown
is used to delete the bridge and restore the Ethernet interface device configuration, it takes the same parameters of qemu-ifup
. The script content is as below,
#!/bin/sh
#
# Script to bring down and delete bridge br0 when QEMU exits
# parameter $1: name of tap such as tap0
# parameter $2: name of the ethernet inferface, such as eth0, p3p1
# Bring down eth0 and br0
#
#/sbin/ifdown eth0
/sbin/ifdown $2
/sbin/ifdown br0
/sbin/ifconfig br0 down
#
#
# Delete the bridge
#
sudo /usr/sbin/brctl delbr br0
#
# bring up eth0 in "normal" mode
#
#/sbin/ifconfig eth0 -promisc
/sbin/ifconfig $2 -promisc
#/sbin/ifup eth0
/sbin/ifup $2
#
# delete the tap device
#
/usr/sbin/openvpn --rmtun --dev $1
#
# start firewall again
#
systemctl start firewalld.service
Booting via TFTP
Earlier QEMU test loaded the kernel uImage into RAM when boot the emulated S3C2440 board. U-boot also support other booting approaches such as TFTP boot and BOOTP. Below test was booting the kernel via TFTP.
Copy the kernel-uImage into directory /var/lib/tftpboot
tftp folder.
[root@localhost qemu]# cp /home/iot/qemu-mini2440/qemu/mini2440/kernel-uImage /var/lib/tftpboot/
Start QEMU, in the u-boot command line, set the IP address as below,
[root@localhost qemu]# ./mini2440/mini2440_start.sh
...(omit...)
MINI2440 # setenv ipaddr 192.168.0.11
Tell u-boot to retrieve uImage named as kernel-uImage
from address 192.168.0.10 and loaded in RAM address 0x30800000.
MINI2440 # tftpboot 0x30800000 192.168.0.10:kernel-uImage
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
TFTP from server 192.168.0.10; our IP address is 192.168.0.11
Filename 'kernel-uImage'.
Load address: 0x30800000
Loading: #######################################################################################################################################################################################################################################################################################################################################################################################
done
Bytes transferred = 5491912 (53ccc8 hex)
After u-boot received the file and put it at address 0x30800000, then u-boot will find from the uImage header that it should relocate the kernel image. Now we can jump to the kernel image by using bootm
command,
MINI2440 # bootm
...omit(start up linux...)
mini2440 login: root
-sh: can't access tty; job control turned off
[root@mini2440 /root]#
[root@mini2440 /root]# ifconfig
eth0 Link encap:Ethernet HWaddr 08:08:11:18:12:27 inet addr:192.168.0.11 Bcast:192.168.0.255 Mask:255.255.255.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:4 errors:0 dropped:0 overruns:0 frame:0TX packets:4 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:332 (332.0 B) TX bytes:280 (280.0 B)Interrupt:51 Base address:0x2300 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0UP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)[root@mini2440 /root]#
Reference
Embedded Linux S3C2440 environment setup
Embedded Linux S3C2440 Environment Startup
Embedded Linux S3C2440 Build and Boot an Image
Embedded Linux S3C2440 Application Development and Debugging
Embedded Linux S3C2440 Networking
Embedded Linux S3C2440 – Kernel Module
Embedded Linux S3C2440 – Kernel Debugging
Embedded Linux S3C2440 – Multi-thread Scheduling
Embedded Linux S3C2440 Profiling
QEMU Wiki
Qt (software) Wiki