# Building Embedded Linux

## การสร้างระบบจำลองสำหรับสถาปัตยกรรม ARM ด้วยชุดเครื่องมือ Buildroot บนโปรแกรม QEMU&#x20;

ทำการติดตั้งโปรแกรมและไลบรารีที่เกี่ยวข้อง

```shell-session
$ sudo apt install autoconf automake libtool libexpat1-dev libncurses5-dev bison flex patch curl cvs texinfo build-essential subversion gawk python-dev gperf ncurses-dev g++ gcc texi2html nfs-kernel-server
```

สร้างไดเรกทอรีสำหรับเก็บ root filesystem ของระบบปฏิบัติการ Embedded Linux ด้วยโปรโตคอลประยุกต์ NFS (Network File System) ผ่านระบบเครือข่าย LAN

```shell-session
$ mkdir ~/nfsroot
```

แล้วทำการตั้งค่าไดเรกทอรีที่ต้องการแชร์ผ่าน NFS ภายในไฟล์ /etc/exports ด้วยคำสั่งข้างล่างนี้

```shell-session
$ sudo nano /etc/exports 
/home/student/nfsroot *(rw,sync,no_root_squash,no_subtree_check)
```

เริ่มเรียกบริการ NFS Server ใหม่อีกครั้ง

```shell-session
$ sudo /etc/init.d/nfs-kernel-server restart
```

ติดตั้งเครื่องมือ buildroot ซึ่งเป็น cross-compiling toolchain

```shell-session
$ wget http://buildroot.uclibc.org/downloads/buildroot-2013.05.tar.gz
$ tar -xzvf buildroot-2013.05.tar.gz 
$ cd buildroot-2013.05/
```

ตั้งค่าระบบปฏิบัติการลีนุกซ์แบบฝังตัวเพื่อให้รองรับรายละเอียดของสถาปัตยกรรมและรายละเอียดอื่นๆดังนี้

```shell-session
$ make menuconfig
```

โดยให้ตั้งค่าดังนี้

| Target Architecture ==> **ARM (little endian)**                                             |
| ------------------------------------------------------------------------------------------- |
| Target Architecture Variant ==> **arm926t**                                                 |
| Target ABI ==> **EABI**                                                                     |
| System Configuration ==> **serial port to run getty on (ttyAMA0)**                          |
| Package Selection ==> **Busybox**                                                           |
| FileSystem Images ==> **cpio the root filesystem และ tar the root filesystem**              |
| Kernel ==> **ระบุชื่อ defconfig เป็น “**<mark style="color:blue;">**versatile**</mark>**”** |
| Kernel ==> **Kernel binary format to zImage**                                               |

{% tabs %}
{% tab title="Target setting" %}

<figure><img src="broken-reference" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="File system setting" %}

<figure><img src="broken-reference" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Kernel setting" %}

<figure><img src="broken-reference" alt=""><figcaption></figcaption></figure>
{% endtab %}
{% endtabs %}

```shell-session
$ make
$ ls -al output/images/
total 6712
drwxr-xr-x 2 student student    4096 2013-07-22 11:45 .
drwxr-xr-x 8 student student    4096 2013-07-22 21:03 ..
-rw-r--r-- 1 student student 1922560 2013-07-22 21:03 rootfs.cpio
-rw-r--r-- 1 student student  858843 2013-07-22 21:03 rootfs.cpio.gz
-rw-r--r-- 1 student student 2181120 2013-07-22 21:03 rootfs.tar
-rw-r--r-- 1 student student 1895000 2013-07-22 11:44 uImage

$ cp output/images/uImage ~/qemu/
```

วาง root filesystem ไปยัง ไดเรกทอรี NFS ชื่อว่า \~/nfsroot ที่เครื่อง Host ได้เปิดแชร์ไว้

```shell-session
$ sudo tar -xvf rootfs.tar ~/nfsroot/
$ sudo chown -R student:student ~/nfsroot
```

ขั้นตอนการสร้าง tun/tap device เพื่อกำหนดวงของระบบเครือข่ายท้องถิ่นภายในระหว่าง QEMU และเครื่อง Host เพื่อให้ระบบปฏิบัติการลีนุกซ์แบบฝังตัวภายใน QEMU สามารถ mount ไดเรกทอรี NFS ที่เปิดแชร์ไว้บนเครื่อง Host ได้ โดยตั้งค่า IP Address ให้กับเครื่อง Host เป็น `192.168.1.1` และตั้งค่า IP Address สำหรับอุปกรณ์ target ซึ่งในที่นี้ก็คือ `192.168.1.101`&#x20;

ขั้นตอนต่อไปทำการติดตั้งโปรแกรม uml-utilities (ที่มีคำสั่ง tunctl) เพื่อให้สามารถจำลองสัญญาณระบบเครือข่าย (network traffic)

```shell-session
$ sudo apt install uml-utilities
$ sudo tunctl -u $(whoami) -t tap1
$ sudo ifconfig tap1 192.168.1.1
$ sudo route add -net 192.168.1.0 netmask 255.255.255.0 dev tap1
$ sudo sh -c "echo  1 > /proc/sys/net/ipv4/ip_forward"
```

ขั้นตอนสุดท้ายทำการรันโปรแกรม QEMU เพื่อจำลองการทำงานบอร์ดสมองกลฝังตัว (Versatile Board) และทำการโหลด root filesystem จากเครื่อง Host&#x20;

```shell-session
$ qemu-system-arm -M versatilepb -m 128M -kernel ~/uImage -append "console=ttyAMA0 root=/dev/nfs rw nfsroot=192.168.1.1:~/nfsroot ip=192.168.1.101" -net nic -net tap,ifname=tap1,script=no -nographic

Set 'tap1' persistent and owned by uid 1000
SIOCADDRT: File exists
Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 3.9.4 (student@marabuntu) (gcc version 4.7.3 (Buildroot 2013.05) ) #1 Mon Jul 22 11:44:32 PDT 2013
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00093177
CPU: VIVT data cache, VIVT instruction cache
Machine: ARM-Versatile PB
Memory policy: ECC disabled, Data cache writeback
sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
Kernel command line: console=ttyAMA0 root=/dev/nfs rw nfsroot=192.168.1.1:/home/student/nfsroot ip=192.168.1.101
PID hash table entries: 512 (order: -1, 2048 bytes)
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
__ex_table already sorted, skipping sort
Memory: 128MB = 128MB total
Memory: 126192k/126192k available, 4880k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    vmalloc : 0xc8800000 - 0xff000000   ( 872 MB)
    lowmem  : 0xc0000000 - 0xc8000000   ( 128 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .text : 0xc0008000 - 0xc0342850   (3307 kB)
      .init : 0xc0343000 - 0xc035f87c   ( 115 kB)
      .data : 0xc0360000 - 0xc0385440   ( 150 kB)
       .bss : 0xc0385440 - 0xc039f78c   ( 105 kB)
NR_IRQS:224
VIC @f1140000: id 0x00041190, vendor 0x41
FPGA IRQ chip 0 "SIC" @ f1003000, 13 irqs
Console: colour dummy device 80x30
Calibrating delay loop... 300.44 BogoMIPS (lpj=1502208)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0xc027e748 - 0xc027e7a0
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
Serial: AMBA PL011 UART driver
dev:f1: ttyAMA0 at MMIO 0x101f1000 (irq = 44) is a PL011 rev1
console [ttyAMA0] enabled
dev:f2: ttyAMA1 at MMIO 0x101f2000 (irq = 45) is a PL011 rev1
dev:f3: ttyAMA2 at MMIO 0x101f3000 (irq = 46) is a PL011 rev1
...
Console: switching to colour frame buffer device 80x60
brd: module loaded
physmap platform flash device: 04000000 at 34000000
physmap-flash physmap-flash.0: map_probe failed
smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <
nico@fluxnic.net
>
eth0: SMC91C11xFD (rev 1) at c8800000 IRQ 57 [nowait]
eth0: Ethernet addr: 52:54:00:12:34:56
mousedev: PS/2 mouse device common for all mice
TCP: cubic registered
NET: Registered protocol family 17
VFP support v0.3: implementor 41 architecture 1 part 10 variant 9 rev 0
eth0: link up
IP-Config: Guessing netmask 255.255.255.0
IP-Config: Complete:
     device=eth0, hwaddr=52:54:00:12:34:56, ipaddr=192.168.1.101, mask=255.255.255.0, gw=255.255.255.255
     host=192.168.1.101, domain=, nis-domain=(none)
     bootserver=255.255.255.255, rootserver=192.168.1.1, rootpath=
input: AT Raw Set 2 keyboard as /devices/fpga:06/serio0/input/input0
input: ImExPS/2 Generic Explorer Mouse as /devices/fpga:07/serio1/input/input1
VFS: Mounted root (nfs filesystem) on device 0:9.
Freeing init memory: 112K
Starting logging: OK
Initializing random number generator... done.
Starting network...
ip: RTNETLINK answers: File exists


Welcome to Burapha Embedded System Lab
Burapha login:  
# ls
# ls -al
total 20
drwxr-xr-x    2 default  default       4096 Jul 23  2013 .
drwxr-xr-x   17 default  default       4096 Jul 23  2013 ..
-rw-------    1 root     root            10 Jul 23  2013 .ash_history
-rw-r--r--    1 default  default          0 May 31  2013 .bash_history
-rw-r--r--    1 default  default        175 May 31  2013 .bash_logout
-rw-r--r--    1 default  default        161 May 31  2013 .bash_profile
#
```
