eth0 에 고정 IP 주소할당하기(static IP address)

by Blogger 하얀쿠아
2017. 1. 18. 00:52 소프트웨어 Note/Embedded Linux


문제

요약: eth0 에 고정 IP주소(static IP address)를 할당하고자 한다.


지난번 포스팅(http://techlog.gurucat.net/277)을 하면서 판다보드에서 살린 두개의 network interface중에서 eth0 에 '192.168.1.1' 과 같이 고정 IP를 할당하고 싶다.

이유는 PC와 판다보드를 LAN cable을 통해 direct연결 한 후, putty와 같은 툴을 사용해서 ssh shell로 연결 하여 개발을 진행하려고 하는 것이다.

판다보드를 부팅한 후, eth0 에 어떻게 고정 IP를 할당할 수 있는가?


해결


할당하려는 IP는 192.168.1.1 이다.


원래는 bootloader에서 argument 읽은 후 kernel로 argument 전달하는 방식을 택하려 했으나, 일단은 더 간단한 방법을 선택했다.


우선 /etc/network/interfaces 를 편집기로 연다.


root@arm:~# cat /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)

# Include files from /etc/network/interfaces.d:

source-directory /etc/network/interfaces.d


auto lo

iface lo inet loopback


allow-hotplug eth0

iface eth0 inet static

address 192.168.1.1

netmask 255.255.255.0

gateway 192.168.1.255


allow-hotplug wlan0

iface wlan0 inet dhcp


파란 색으로 표시한 것과 같이 기술해 준다.


이상.



재부팅을 하고 확인해보면 아래와 같이 ip address가 할당된 것을 볼 수 있다.


root@arm:~# ifconfig

eth0      Link encap:Ethernet  HWaddr c6:f3:ca:97:cf:67

          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0

          inet6 addr: fe80::c4f3:caff:fe97:cf67/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:226 errors:0 dropped:0 overruns:0 frame:0

          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:18954 (18.9 KB)  TX bytes:4397 (4.3 KB)


lo        Link encap:Local Loopback

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


wlan0     Link encap:Ethernet  HWaddr de:ad:be:ef:00:00

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


그런데.. 문제가 있다.

sshd 가 부팅되면서 시작되었다가 곧바로 종료된다.

그래서 ssh shell을 사용하지 못하고, 아직 serial로 연결해서 작업을 진행중이다.



Next Action Item


sshd의 시작 직후 종료되는 원인을 찾고, sshd가 부팅되면서 정상적으로 실행되도록 수정하는 것이다.

이 댓글을 비밀 댓글로

[임베디드/판다보드] Networking Interface Initialize

by Blogger 하얀쿠아
2017. 1. 10. 21:33 소프트웨어 Note/Embedded Linux


문제현상

판다보드에서 리눅스를 부팅한 후, ifconfig로 확인해보면 'lo' 라고 표시되는 loopback interface (127.0.0.1) 만 bring up되고, eth0(ethernet)과 wlan0(Wi-Fi interface)는 자동으로 bring up되지 않는다.

'ifconfig up wlan0', 'ifconfig up eth0' 을 사용해서 커맨드라인에서 수동으로 bring up 을 해보면, 정상적으로 bring up 되는 것을 확인했다.


부팅시퀀스에서 bring up 되도록 하는 방법이 있을 텐데 비활성화 되어 있는 것 같다.

어느 부분을 수정해야 하는지 내가 모르고 있는 것 같아서, 찾아보았다.


해결


우선 판다보드의 네트워크 인터페이스를 확인해보았다.


root@arm:~# ls -l /sys/class/net/

total 0

lrwxrwxrwx 1 root root 0 Feb 11 16:28 eth0 -> ../../devices/platform/44000000.ocp/4a064000.usbhshost/4a064c00.ehci/usb1/1-1/1-1.1/1-1.1:1.0/net/eth0

lrwxrwxrwx 1 root root 0 Feb 11 16:28 lo -> ../../devices/virtual/net/lo

lrwxrwxrwx 1 root root 0 Feb 11 16:28 wlan0 -> ../../devices/platform/44000000.ocp/480d5000.mmc/mmc_host/mmc1/mmc1:0001/mmc1:0001:2/wl12xx.2.auto/net/wlan0




wlan0와 eth0는 존재하는걸 확인했다.

Wi-Fi를 위한 firmware는 rootfs만드는 과정에서 미리 /lib/firmware/ti-connectivity 에 받아 두었으므로 따로 준비할 필요는 없는 상황이다.


root@arm:~# ls -l /lib/firmware/ti-connectivity/

total 8792

-rw-r--r-- 1 root root  48909 Sep 18  2016 TIInit_7.2.31.bts

-rw-r--r-- 1 root root 194180 Apr 25  2016 wl1251-fw.bin

-rw-r--r-- 1 root root    752 Apr 25  2016 wl1251-nvs.bin

-rw-r--r-- 1 root root 273880 Sep 18  2016 wl1271-fw-2.bin

-rw-r--r-- 1 root root 272836 Sep 18  2016 wl1271-fw-ap.bin

-rw-r--r-- 1 root root 271832 Sep 18  2016 wl1271-fw.bin

lrwxrwxrwx 1 root root     14 Jul 21  2016 wl1271-nvs.bin -> wl127x-nvs.bin

-rw-r--r-- 1 root root 280388 Sep 18  2016 wl127x-fw-3.bin

-rw-r--r-- 1 root root 260852 Apr 25  2016 wl127x-fw-4-mr.bin

-rw-r--r-- 1 root root 261892 Apr 25  2016 wl127x-fw-4-plt.bin

-rw-r--r-- 1 root root 276684 Apr 25  2016 wl127x-fw-4-sr.bin

-rw-r--r-- 1 root root 354600 Apr 25  2016 wl127x-fw-5-mr.bin

-rw-r--r-- 1 root root 352588 Apr 25  2016 wl127x-fw-5-plt.bin

-rw-r--r-- 1 root root 370996 Apr 25  2016 wl127x-fw-5-sr.bin

-rw-r--r-- 1 root root 267496 Sep 18  2016 wl127x-fw-plt-3.bin

-rw-r--r-- 1 root root    912 Jul 21  2016 wl127x-nvs.bin

-rw-r--r-- 1 root root 284784 Sep 18  2016 wl128x-fw-3.bin

-rw-r--r-- 1 root root 264904 Apr 25  2016 wl128x-fw-4-mr.bin

-rw-r--r-- 1 root root 269424 Apr 25  2016 wl128x-fw-4-plt.bin

-rw-r--r-- 1 root root 284156 Apr 25  2016 wl128x-fw-4-sr.bin

-rw-r--r-- 1 root root 359140 Apr 25  2016 wl128x-fw-5-mr.bin

-rw-r--r-- 1 root root 360452 Apr 25  2016 wl128x-fw-5-plt.bin

-rw-r--r-- 1 root root 378988 Apr 25  2016 wl128x-fw-5-sr.bin

-rw-r--r-- 1 root root 265460 Sep 18  2016 wl128x-fw-ap.bin

-rw-r--r-- 1 root root 273324 Sep 18  2016 wl128x-fw.bin

-rw-r--r-- 1 root root 271932 Sep 18  2016 wl128x-fw-plt-3.bin

-rw-r--r-- 1 root root   1113 Jul 21  2016 wl128x-nvs.bin

lrwxrwxrwx 1 root root     14 Jul 21  2016 wl12xx-nvs.bin -> wl127x-nvs.bin

-rw-r--r-- 1 root root 639276 Apr 25  2016 wl18xx-fw-2.bin

-rw-r--r-- 1 root root 673328 Apr 25  2016 wl18xx-fw-3.bin

-rw-r--r-- 1 root root 745228 Dec 31  2016 wl18xx-fw-4.bin

-rw-r--r-- 1 root root 413860 Sep 18  2016 wl18xx-fw.bin




우선 interface 파일을 확인해보았다.


root@arm:~# ls -l /etc/network/interfaces

-rw-r--r-- 1 root root 261 Feb 11 16:32 /etc/network/interfaces

root@arm:~# cat /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)

# Include files from /etc/network/interfaces.d:

source-directory /etc/network/interfaces.d


auto lo

iface lo inet loopback




'lo' 인터페이스에 대해서만 설정되고 있는 것이 보인다.

이 파일을 열고 eth0와 wlan0에 대한 내용을 추가했다.


root@arm:~# cat /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)

# Include files from /etc/network/interfaces.d:

source-directory /etc/network/interfaces.d


auto lo

iface lo inet loopback


allow-hotplug eth0

iface eth0 inet manual


allow-hotplug wlan0

iface wlan0 inet dhcp




재부팅을 한 후 ifconfig로 확인해보면 아래와 같이 추가된 인터페이스를 확인 할 수 있다.


root@arm:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 8e:16:3e:3d:2b:e5

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


lo        Link encap:Local Loopback

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


wlan0     Link encap:Ethernet  HWaddr de:ad:be:ef:00:00

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)



작업하면서 시행착오를 겪은 부분이 있는데,

allow-hotplug가 아닌 auto eth0, auto wlan0 로 추가를 했더니, 부팅과정에서 커널 로드 후 systemd가 각 service 파일을 차례로 시작하다가 interface up하는 부분에서 무한 대기상태로 빠지는 것이었다.


문득, interface up을 담당하는 service가 어떤건지 궁금해졌다.
현재 판다보드에서 동작중인 리눅스는 ubuntu 16.04 이다.
정확하게 어떤 버전부터인지는 모르겠으나 ubuntu 16.04는 기존의 init.d script를 systemd로 대체한 것으로 보인다.

root@arm:~# ls -l /sbin/init
lrwxrwxrwx 1 root root 20 Sep  7  2016 /sbin/init -> /lib/systemd/systemd


systemd에 대한 자세한 내용은 다른 포스팅에서 다루어 보고자 한다.
일단, systemd는 커맨드라인에서 인터페이스 툴을 제공해 주고 있는데, 그 이름은 'systemctl' 이다.
이 툴을 사용해서 networking service 에 대한 정보를 확인해보았다.

root@arm:~# systemctl cat networking
# /lib/systemd/system/networking.service
[Unit]
Description=Raise network interfaces
Documentation=man:interfaces(5)
DefaultDependencies=no
Wants=network.target
After=local-fs.target network-pre.target apparmor.service systemd-sysctl.service
Before=network.target shutdown.target network-online.target
Conflicts=shutdown.target

[Install]
WantedBy=multi-user.target
WantedBy=network-online.target

[Service]
Type=oneshot
EnvironmentFile=-/etc/default/networking
ExecStartPre=-/bin/sh -c '[ "$CONFIGURE_INTERFACES" != "no" ] && [ -n "$(ifquery
ExecStart=/sbin/ifup -a --read-environment
ExecStop=/sbin/ifdown -a --read-environment
RemainAfterExit=true
TimeoutStartSec=5min

# /run/systemd/generator/networking.service.d/50-insserv.conf-$network.conf
# Automatically generated by systemd-insserv-generator

[Unit]
Wants=network.target
Before=network.target


systemctl cat 은 각 service unit의 동작방식을 정의한 파일의 내용을 보여주는 명령이다.

간단히 설명 부분만 확인해보면, 'Raise network interfaces' , 찾았다 요놈.

네트워크 인터페이스를 올려주는 놈이란다.

내가 찾던 놈이구만.


Type=oneshot 인 걸로 봐서, 부팅될 때 한번만 실행 하고 끝내는 놈이지 싶다.

확인해봐야지.

networking service상태에 대해 살펴보자.


root@arm:~# systemctl status networking

● networking.service - Raise network interfaces

   Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor prese

  Drop-In: /run/systemd/generator/networking.service.d

           └─50-insserv.conf-$network.conf

   Active: active (exited) since Thu 2016-02-11 16:28:07 UTC; 27min ago

     Docs: man:interfaces(5)

  Process: 284 ExecStart=/sbin/ifup -a --read-environment (code=exited, status=0

  Process: 262 ExecStartPre=/bin/sh -c [ "$CONFIGURE_INTERFACES" != "no" ] && [

 Main PID: 284 (code=exited, status=0/SUCCESS)

   CGroup: /system.slice/networking.service


Feb 11 16:28:05 arm systemd[1]: Starting Raise network interfaces...

Feb 11 16:28:07 arm systemd[1]: Started Raise network interfaces.


자세히는 모르겠지만, 대충 살펴보면, load 되었고, active 상태인데, exited 상태이기도 하다.

그 아래를 보면, 284 PID를 갖는 process로 /sbin/ifup 을 실행 했던 것으로 보인다.

argument로 --read-environment 라는게 있는 걸로 보아, 뭔가 환경변수나 환경설정을 읽어서 interface up 을 했을 것으로 추정된다.


좋아, 다시 보자.

'systemctl cat networking' 을 통해 확인 했던 부분중에,

EnvironmentFile=-/etc/default/networking 라는 부분이 있는 것을 발견했다.


root@arm:~# cat /etc/default/networking

# Configuration for networking init script being run during

# the boot sequence


# Set to 'no' to skip interfaces configuration on boot

#CONFIGURE_INTERFACES=yes


# Don't configure these interfaces. Shell wildcards supported/

#EXCLUDE_INTERFACES=


# Set to 'yes' to enable additional verbosity

#VERBOSE=no


별다른 내용은 없는데, 주석들을 읽어보면, boot sequence 동안에 실행되는 networking init script의 설정파일쯤 되는놈인것 같다.

그런데 죄다 주석처리되어서, 딱히 하는 일은 없는 것으로 보인다.

OK. 이놈은 통과..


현재 내가 궁금한 것은 '/etc/network/interfaces' 이놈을 누가 읽는가 하는 부분인데.

ifup이 읽는 default 파일인 것으로 추정된다.. 

ifup --help 로 확인해보면 아래와 같다.


root@arm:/lib/systemd/system# ifup --help

Usage: ifup <options> <ifaces...>


Options:

        -h, --help             this help

        -V, --version          copyright and version information

        -a, --all              process all interfaces marked "auto"

        --allow CLASS          ignore non-"allow-CLASS" interfaces

        -i, --interfaces FILE  use FILE for interface definitions

        -X, --exclude PATTERN  exclude interfaces from the list of

                               interfaces to operate on by a PATTERN

        -n, --no-act           print out what would happen, but don't do it

                               (note that this option doesn't disable mappings)

        -v, --verbose          print out what would happen before doing it

        -o OPTION=VALUE        set OPTION to VALUE as though it were in

                               /etc/network/interfaces

        --no-mappings          don't run any mappings

        --no-scripts           don't run any hook scripts

        --no-loopback          don't act specially on the loopback device

        --force                force de/configuration

        --ignore-errors        ignore errors


-a 옵션은 'auto' 로 표시된 모든 인터페이스를 처리한다는 옵션이다.

--read-environment 라는 옵션은 없다.


또한 설명에 /etc/network/interfaces 에 대한 내용이 있는 걸로 미루어 봐서, interface 정의 하는 default 파일경로인 것 같다.


Next Action Item

이제 해보려는 작업은 두가지다.

1. eth0 에 '192.168.1.1' 이라는 ip를 boot argument로 설정되도록 하는 작업 ( 바로가기 )

2. wlan0 와 연동해서 Wi-Fi stack (wpa-supplicant)을 booting time에 실행되도록 하는 작업



이 댓글을 비밀 댓글로

Kernel command line 보는 방법

by Blogger 하얀쿠아
2017. 1. 5. 01:44 소프트웨어 Note/Embedded Linux

Linux kernel command line, boot argument


동작중인 kernel의 shell상에서 command line parameter를 보는 방법은 아래와 같다.

이를 'boot arguments' 라고도 한다.


$ cat /proc/cmdline


여기에는 linux kernel이 부팅할 때 필요한 여러가지 정보들을 kernel에게 넘겨주는 형태로 사용한다.

예를들면 root device나 network configuration등에 대한 정보들 말이다.


boot loader에서 linux kernel로 변수정보 넘기기

boot loader에서 linux kernel로 정보를 넘길때도 사용할 수 있다.

U-boot 에서는 'bootargs' 라는 변수의 값을 자동으로 linux kernel 부팅시키면서 넘긴다.

U-boot command line에서 아래와 같이 환경변수를 선언하면, bootargs 뒤의 'root=/dev/ram rw' 가 bootargs의 내용이 되며, 이 값이 kernel로 전달된다.


setenv bootargs root=/dev/ram rw


참고로 U-boot 는 Hush shell을 사용한다. (bourne shell과 유사함)


참고 : http://www.denx.de/wiki/DULG/LinuxKernelArgs

이 댓글을 비밀 댓글로

PandaBoard ES : 부팅용 SD card 준비

by Blogger 하얀쿠아
2016. 12. 16. 00:50 소프트웨어 Note/Embedded Linux

PandaBoard ES : 보드 부팅을 위한 SD card 준비


TI 의 ARM Cortex A9 기반의 임베디드 보드인 PandaBoard ES에는 내장된 별도의 저장공간이 없다.

대신에 sd card슬롯을 제공하고, sd카드의 boot partition을 통해 부팅을 하게된다.

아무래도 trial(시험용) 보드 성격이 강해서 그런 것이리라..


우선 판다보드 부팅에 사용할 sd카드를 준비하는 작업이 필요하다.

다음 순서로 진행할 것이다.


1. SD카드 파티션 분할 및 각 파티션 포맷

2. U-Boot 소스코드 다운로드 및 빌드

3. Linux Kernel 소스코드 다운로드 및 빌드

4. Ubuntu의 Root File System 확보 및 SD카드에 복사

5. Wi-Fi driver firmware 확보 및 SD카드에 복사

6. /etc/fstab를 통해 각 파티션을 자동마운트 되도록 수정



파티션 구성


아래와 같이 4개의 파티션으로 구성했다.

16GB SD카드를 우분투로 동작중인 host pc에 꽂으니 /dev/sdc 로 인식되었다.

이를 sdc1 ~ sdc4 까지 4개의 파티션으로 나누었다.


이 부분은 각자의 환경에 따라 다르게 인식될 수 있다.

즉, /dev/sdb가 될 수도 있고... /dev/sdd가 될 수도 있으며.. /dev/mmcblk0 이런식이 될 수도 있다.



Command (m for help): p
Disk /dev/sdc: 14.7 GiB, 15719727104 bytes, 30702592 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6114984e

Device     Boot    Start      End  Sectors  Size Id Type
/dev/sdc1  *        2048  2099199  2097152    1G  c W95 FAT32 (LBA)
/dev/sdc2        2099200 23070719 20971520   10G 83 Linux
/dev/sdc3       23070720 27265023  4194304    2G 83 Linux
/dev/sdc4       27265024 30702591  3437568  1.7G 82 Linux swap / Solaris


sdc1는 부팅 파티션으로, u-boot.img와 MLO를 넣고, boot flag를 true로 했다.

filesystem type은 FAT32 (LBA)로 하였다.


sdc2는 리눅스를 위한 root 파티션으로, 10GB를 할당했고, filesystem type은 ext4로 했다.

sdc3은 리눅스의 /var 디렉토리를 위한 파티션으로, 2GB를 할당했다. filesystem type은 ext4로 했다.

sdc4는 리눅스의 swap 파티션으로 남은 공간 전체를 할당했다.


파티션 포맷 (Format Partition)


나누어둔 파티션을 실제로 사용하기 위해서는 각각의 파티션을 포맷해야 한다.


jeon@ubuntu:~$ sudo mkfs.vfat -F 32 -n boot /dev/sdc1
[sudo] password for jeon:
mkfs.fat 3.0.28 (2015-05-16)
mkfs.fat: warning - lowercase labels might not work properly with DOS or Windows


jeon@ubuntu:~$ sudo mkfs.ext4 -L rootfs /dev/sdc2
mke2fs 1.42.13 (17-May-2015)
Creating filesystem with 2621440 4k blocks and 655360 inodes
Filesystem UUID: 1257cd67-576f-47f8-a55b-d2c8c2a81539
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                           
Writing inode tables: done                           
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done


jeon@ubuntu:~$ sudo mkfs.ext4 -L data /dev/sdc3
mke2fs 1.42.13 (17-May-2015)
Creating filesystem with 524288 4k blocks and 131072 inodes
Filesystem UUID: c38ba4aa-a430-4d3f-b5ca-d5edce08379f
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912

Allocating group tables: done                           
Writing inode tables: done                           
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done


jeon@ubuntu:~$ sudo mkswap -c -L swap /dev/sdc4
0 bad pages
Setting up swapspace version 1, size = 1.7 GiB (1760030720 bytes)
LABEL=swap, UUID=fa0383da-57ed-4a06-8e9a-e4a4a3659b85



커널 소스 확보 및 빌드


Pandaboard ES에서 사용할 커널이미지를 만들기 위해서, 직접 커널 소스를 빌드하기로 했다.

최대한 그런 일은 없어야 겠지만, 커널 수정이 필요할 경우가 발생하면... 수정의 용이성을 위해서이다.

만약 미리 빌드된 커널이미지를 보드에 올려서 사용한다면, 커널 수정이 필요한 순간, 일치하는 커널 소스를 찾고 빌드환경 만들고... 좀 번거로울 것이기 때문에.

처음부터 미리 번거롭기로 했다.(?)


CPU architecture 별로 커널 빌드를 위한 스크립트를 제공하는 고마운 git 저장소가 있다.



https://github.com/RobertCNelson/armv7-multiplatform/tree/v4.9.x



/dev/sdc2로 root file system 복사

ubuntu 16.04 LTS의 file system을 구해서 2번째 파티션 (리눅스의 root파티션)에 복사해 넣었다.

리눅스의 커널이미지와는 별개로, 우리는 리눅스 배포판의 root file system이 필요하다.

왜 이런 작업이 필요하나면...

커널이미지는 말그대로 커널부분만을 제공한다.

다시말하면 /usr/bin/ 에 존재하는 실행파일들... 즉 여러가지 커맨드들을 사용한다거나..

/etc 아래 존재하는 리눅스의 설정파일등을 통해 리눅스 설정을 한다거나...

systemd등을 통해 부팅시점에 여러가지 데몬들을 띄우거나 소켓을 생성하거나 ... 등등의 작업들은 커널이미지가 제공하지 않는다는 것이다.

이걸 일일히 코드를 구해서, 크로스컴파일 하고... directory 를 구조에 맞게 만들고... 직접하려면 번거로울 것 이다. 물론 한번 해보면 좋은 경험은 되겠지.


이런 것을 제공하기 위해 누군가가 미리 만들어둔 linux root file system을 구해다가 단순히 sd카드에 복사해 넣는 것으로 끝이다.



다운로드

wget -c https://rcn-ee.com/rootfs/eewiki/minfs/ubuntu-16.04.1-minimal-armhf-2016-09-17.tar.xz



파일 검증

sha256sum ubuntu-16.04.1-minimal-armhf-2016-09-17.tar.xz
2883cdd3416e0bd5988aa351c88db72ca089a184c5a670662d750568ca0869d8  ubuntu-16.04.1-minimal-armhf-2016-09-17.tar.xz


압축해제

tar xf ubuntu-16.04.1-minimal-armhf-2016-09-17.tar.xz


참고로 이 ubuntu의 계정은 'ubuntu'이고 암호는 'temppwd' 이다.



root file 복사하기

sudo mount /dev/sdc2 /media/rootfs
sudo tar xfvp ./*-*-*-armhf-*/armhf-rootfs-*.tar -C /media/rootfs/



파일시스템 테이블 (/etc/fstab)


이 작업을 해두어야, 부팅시 자동으로 마운트가 된다.

/media/rootfs//etc/fstab 는 처음에 아무런 내용이 없이 주석이 달린 1줄만 있다.

나는 4개의 파티션으로 나누었으므로 아래와 같이 mount point및 mount option등을 지정해 주었다.

만약 fstab에 대해 익숙하지 않다면, 이에 대해 알아볼 것은 권한다.

내용은 많지 않으나, 여기서는 자세히 다루지 않겠다.


jeon@ubuntu:/media/jeon/rootfs$ cat etc/fstab
# UNCONFIGURED FSTAB FOR BASE SYSTEM
/dev/mmcblk0p1  /boot  vfat  errors=remount-ro  0  0
/dev/mmcblk0p2  /  ext4  errors=remount-ro  0  1
/dev/mmcblk0p3  /var  ext4  auto  0  0
/dev/mmcblk0p4  none  swap  sw  0  0


간략히 알아보면, fstab은 총 6개의 부분으로 나누어져 있다.

첫번째는 File System Device Name, 두번째는 Mount Point, 세번째는 FileSystem Type, 네번째는 Mount Option, 다섯번째와 여섯번째 숫자의 의미는 각각 Dump할지 말지여부와 File Sequence Check Option값 이다.



이 댓글을 비밀 댓글로

리눅스에서의 세마포어 (Semaphores in Linux)

by Blogger 하얀쿠아
2012. 10. 7. 15:25 소프트웨어 Note/Linux

리눅스에서의 세마포어 (Semaphores in Linux)



 일반적으로 상용 어플리케이션은 멀티스레드 어플리케이션이다.

 상용 어플리케이션중 멀티스레드가 아닌 어플리케이션은 상상하기 힘들다.

어플리케이션과 시스템의 성능(응답성)을 높이기 위해서 어플리케이션은 반드시 멀티스레드를 이용한 접근을 해야만 한다. 그러나, 인생의 대부분은 대가없이 얻어지는 것은 없듯이, 어플리케이션에서 멀티스레드의 특성을 활용해야 할 필요가 있다면, 다음과 같은 몇가지 이슈와 부딪히게 된다. 


바로 교착상태(dead lock), 경쟁상태(race condition), 스레드의 잘못된 동작 등이다.

 이러한 이슈들을 극복하기위해, 운영체제는 뮤텍스, 세마포어, 시그널, 배리어와 같은 도구모음을 제공하여, 멀티프로세스와 멀티스레드 환경에서의 문제를 해결한다.

 이 포스팅은 이러한 도구중 하나인 세마포어에 대해 논의하고, 그것들에 대한 몇가지 심화적인 내용을 제공한다.



세마포어 개요

 세마포어는 사실 간단하다. 세마포어는 자원의 상태를 나타내는 간단한 카운터로 생각할 수 있다. 

그런데, 이 카운터는 사용자가 임의대로 접근 할 수는 없는 보호받는 변수라고 가정해보자.

그리고 리눅스에서 이러한 변수의 보호장치는 바로 '커널'이다.


이 세마포어 변수의 사용법은 간단하다. 만약 카운터가 0보다 크다면, 자원은 사용가능한 것이고, 카운터가 0이거나 0보다 작다면 자원은 busy 상태이거나 다른 누군가에 의해 사용되고 있는 것이다. 이 간단한 메커니즘이 멀티스레드나 멀티프로세스 기반의 어플리케이션의 동기화를 돕는다.

 

세마포어는 Edsger Dijkstra(에드거 다익스트라)에 의해 개발 및 제안되었고, 리눅스를 비롯한 오늘날의 여러 운영체제들에서 동기화(Synchronization)의 목적으로 사용되곤 한다. 같은 메커니즘은 이제 어플리케이션 개발자 역시 사용할 수 있다. 동기화 메커니즘은 또한 프로세스간 통신(IPC)에서도 가장 중요한 요소 중 하나이다.


세마포어는 공유되는 자원의 개수에 따라 2진(Binary, 바이너리) 세마포어가 될 수도 있고 계수(Counting, 카운팅) 세마포어가 될 수도 있다. 만약 단일 자원이 사용된다면, 단지 하나의 세마포어만을 동기화목적으로 사용 할 수 있다. 이런 경우에 세마포어는 2진(바이너리) 세마포어이다. 사용자간 공유되는 자원의 수가 하나보다 큰 이외의 모든 경우에는 카운팅 세마포어로서, 2개 이상의 세마포어를 사용할 수 있다.


세마포어는 기본적으로 2개의 동작(Operation)으로 구현한다. 


하나는 세마포어 변수를 기다리는 것이고, 다른 하나는 세마포어 변수에 시그널을 보내는 것이다. 세마포어는 카운터만은 아니기 때문에 다음의 알고리즘이 두개의 세마포어 오퍼레이션을 표현한다.




가정:

s는 세마포어 변수이다.

W(s)  는 세마포어를 대기하는 것을 나타낸다.

P(s) 는 세마포어에 시그널을 보낼수 있음을 의미한다.


알고리즘:


W(s)

while (s <= 0) {
	//do nothing
}
s=s-1;


P(s)

s=s+1;


위의 알고리즘으로 부터 세마포어의 대기연산은 세마포어 카운터에서 1을 감소하는 것 외에는 아무것도 하지 않음을 쉽게 이해 할 수 있다. 시그널을 보내는 연산은 정확히 반대로, 세마포어 카운터를 1 증가한다.




Difference Between Semaphores and Mutex

 여기까지 읽었다면 몇가지 명확한 차이가 드러난다. 그러나 뮤텍스와 세마포어의 두드러진 차이점을 다시한번 여기서 짚고 넘어가보자.


1. 세마포어는 뮤텍스가 될 수 있지만, 뮤텍스는 세마포어가 될 수 없다. 

이것은 간단히 말해서 binary 세마포어는 뮤텍스로써 사용가능하지만, 뮤텍스는 결코 세마포어로써의 기능을 보여 줄 수 없다.(counting 세마포어로써의 기능을 말함)


2. 세마포어와 뮤텍스 둘 다 (적어도 최신 커널에서는, 2007년 기준) 자연스럽게 비 재귀적이다.


3. 세마포어는 무엇에도 소유되지 않는다. 반면에 뮤텍스는 소유되며, 뮤텍스 소유자는 그것들에 대해 책임이 있다. 이것은 디버깅 측면에서 중요한 차이점이다.


4. 뮤텍스의 경우, 뮤텍스를 소유한 스레드가 뮤텍스를 해제해야할 책임이 있다. 그러나 세마포어의 경우에는, 이런 상태가 필요없다. 다른 어떤 스레드들도 세마포어를 해제하기 위해 sem_post( ) 함수를 사용해서  신호를 보낼 수 있다.


5. 결정적으로 뮤텍스는 재진입 코드의 영역(크리티컬 섹션)으로의 연결을 직렬화 하는데 사용되고, 하나보다 많은 (2개 이상의 ) 스레드가 병행적으로 (concurrently) 실행할 수 없다. 정의에 의하면 세마포어는 최대 숫자까지 공유자원에 대한 사용자의 동시 사용을 제한한다. 



이 댓글을 비밀 댓글로

리눅스 압축 tar gzip bzip2 zip 해제/압축 방법

by Blogger 하얀쿠아
2011. 11. 27. 15:57 소프트웨어 Note/Linux

리눅스 압축 명령/방법/종류


리눅스에서 많이 사용되는 압축파일로는 tar, gz, bz2, zip 등이 있다. 




이들 각각은 나름대로의 고유한 압축방식을 가지고 있으며, 압축해제하는 방법 또한 다양하다.

그래픽 유저 인터페이스(GUI) 모드에서 리눅스를 사용하는 사람이라면 간단히 더블클릭으로 압축 관리 프로그램을 실행하여 압축 및 해제를 할 수 있지만, 텍스트 모드를 사용하는 상황이라면 이들 압축파일을 사용할 수 있는 명령들을 숙지하고 있을 필요가 있다.


오늘은 이러한 압축 파일들을 생성하고 압축해제하는 방법에 대해 알아보도록 하자.



.tar 파일

tar은 엄밀히 말해서 압축방식은 아니고, 일종의 묶음 파일로 이해하자.

이 tar과 gzip을 같이 사용하는 경우 tar.gz (또는 tgz)라는 확장자를 사용하게 된다.

tar 로 묶고 푸는 방법은 다음과 같다.

 


압축 생성

  # tar cvf temp.tar temp/

    ; temp 디렉터리를 temp.tar 이라는 파일로 묶는다.

     (temp 디렉터리와 그 이하의 모든 파일 및 디렉터리)

 

압축 해제

  # tar xvf temp.tar

 

옵션설명

  -c : (create) 압축 파일을 생성한다.

  -x : (extract) 압축 파일을 해제한다.

  -v : 압축파일이 생성(해제)되는 과정을 보여준다.

  -f : 압축파일 또는 Archive 장치를 사용한다.


참고사항

※ tar 명령에서 옵션 앞에 붙는 "-" 기호는 붙여도 되고, 붙이지 않아도 된다.

※ gzip과 같이 압축된 파일의 경우 (tar.gz 또는 tgz) -z 옵션을 사용하여 한번에 처리할 수 있다.

 


gzip (tar.gz 또는 tgz)

 앞서 보았던 tar로 묶여진 파일을 다시 압축하는 방법으로 많이 사용되는 압축형태이다. 

gzip 명령으로 압축하고 gunzip 명령으로 압축을 해제한다.

 

압축 생성

  # gzip temp.tar

  위 명령을 사용하면 temp.tar.gz 이라는 파일이 생성된다.

 

압축 해제

  # gunzip temp.tar.gz

  # gzip -d temp.tar.gz


참고사항 

※ gzip 명령으로 압축을 해제하면, 그 전단계인 tar 묶음 형태로 압축이 풀리게 되므로 tar 명령으로 다시한번 묶음을 해제해야 한다.

최근에는 이러한 번거로운 과정을 줄이기 위해 tar 명령에서 tar 묶음 및 gzip 압축까지 모두 해제할 수 있는 옵션인 '-z' 옵션이 제공된다.


아래와 같이 응용할 수 있다.


  # tar xzvf temp.tar.gz

  

 

bzip2 (bz2)

gzip과 같이 최근 많이 사용되는 압축 형태로 tar.bz2 라는 확장자로 다루어진다.

역시 tar 묶음에 다시 압축을 가하는 형태이며, bzip2 전용 명령도 있으며, tar에서도 한번에 사용할 수 있는 옵션(-j)이 있다.

 

압축 생성

  # bzip2 -zkv temp.tar

 

압축 해제

  # bunzip2 temp.tar.bz2


참고사항 

※ bzip2 명령으로 압축을 해제하면, tar 명령을 다시 사용해야 하므로, 최근에는 tar에서 바로 해제하는 경우가 많다.

  # tar xjvf temp.tar.bz2



zip

zip 파일은 Windows에서도 많이 사용되는 압축 형태로, 리눅스에서도 동일하게 사용할 수 있다.

 

압축 생성

  # zip -v temp.zip temp/*

    ; temp 디렉터리 이하의 모든 파일을 zip으로 압축한다.

 

압축 해제

  # unzip temp.zip



알아두면 도움되는 Tip

리눅스에서는 Windows와 달리, 파일의 확장자에 큰 의미를 두지 않으므로, 압축파일 생성시 이름 및 확장자를 임의로 지정할 수도 있다.

그러나 사용자 간의 커뮤니케이션 및 인식의 통일을 위해 가급적 지정된 확장자를 사용하는 것이 좋다.

즉 압축파일 생성시 아래와 같은 일련의 규칙들을 준수해 줌으로써 쉽게 인식하고 혼란을 막아, 다른 사용자의 이해를 높일 수 있다.


쉽게말하면, zip으로 압축하고 확장자를 'tar' 이런식으로 바꿔서 다른사람한테 전달하면, 

그 다른사람은 tar로 풀려고 시도를 하는 등의 삽질을 하게 된다는 말.

 

그러니깐, 아래와 같은 압축파일 확장자 규칙을 따르면 좋을 것 같다.


tar압축 : *.tar

tar/gzip 압축 : *.tar.gz / *.tgz

tar/bzip2 압축 : *.tar.bz2

이 댓글을 비밀 댓글로