ubuntu 20.04로 가상환경을 셋팅하겠다.
서버용으로는 레드햇이나 센토스 같은 배포판을 많이 쓰고,
개발용으로는 우분투를 많이 쓰게 되었다.
개발용으로 우분투를 많이 쓰게 된 이유는 안드로이드 개발 환경에 올라갔던 리눅스 배포판이 우분투였기 때문이다.
리눅스 배포판이 나온 이유는 최초에 리눅스 관련 커널을 전부 받아서 그것을 빌드하는 것 조차 어려웠다. 그것이 비전문가에게 너무나 어려운 작업이었기 때문에 배포판이 나오게 되었다.
Unix를 PC에서 실행할 수 있도록 만들어놓은 것이 Linux이다.
22.04 버전이라는 것은 22년 04월에 나왔다는 의미이다.
우리가 쓰는 20.04버전은 20년 04월에 나온 것이다.
우분투는 1년에 2번씩 6개월 텀으로 배포를 한다. 그래서 4월과 10월에 배포판이 나온다. 그런데 늘 우리가 "짝수년도.04" 버전만 쓰는 이유는 "짝수년도 .04버전"이 LTS버전(Long term support)으로 제공되기 때문이다.
우리는 BSP를 만질 것인데, 그것들을 하는데 안정적인 버전이 20.04버전이다. 리눅스 BSP가 빌드 될 당시의 버전인 20.04를 실습환경으로 쓰는 것이다. 22.04로 하면 호환이 안되서 빌드가 안된다.
운영체제마다 사용하는 파일시스템이 다르다. 윈도우가 쓰는 파일시스템과 리눅스가 쓰는 파일시스템이 다르기 때문에 둘은 호환이 안되는 것이다.
윈도우는 파일시스템으로 NTFS를 사용하고, 리눅스는 파일시스템으로 EXT를 사용한다.
네트워크 프로토콜은 전부 빅엔디안을 쓰게 되어있다.
그래서 네트워크 프로토콜에서는 리틀엔디안이 들어오면 자동으로 빅엔디안으로 바꿔주는 기능이 포함되어있다.
당연히 반대도 가능하다.
그러나 우리가 하고 싶은것은 위의 경우이기 때문에 위의 상황을 달성하기 위해 셋팅작업을 시작하겠다.
VMware와 VirtualBox 두개가 대표적인 윈도우용 가상머신인데
====================================================================================
1.가상머신 새로 만들기
2.이름 : ubuntu20.04
3.메모리 : 8192MB
4.프로세서: 4개
5.하드디스크 : 150Gb
6.설정 -> 디스플레이 -> 그래픽컨트롤러 : VBoxSVGA
설정 -> 저장소 -> 광학 드라이버(가상 씨디롬) 추가버튼 -> ubuntu20.04.6.~.iso 선택
설정 -> 네트워크 -> '어댑터에 브리지' 선택(윈도우-라즈베리-리눅스를 하나의 아이피 네트워크로 쓰기 위함)
7.시작 , 한국언 선택 , 우분투 설치 , 일반설치 , 설치중 업데이트 안함 체크 해제
이름 : ubuntu, 컴퓨터 이름 : ubuntuXX (01~23 : 윈도우 IP 끝번호 - 20) , 암호 설정 -> ubuntu 설치 완료
8.재부팅 후 설정 -> 네트워크 -> ipv4 -> ip :10.10.15.xx (윈도우IP+20), 넷마스크 : 255.255.255.0 게이트웨이 : 10.10.15.254, DNS : 8.8.8.8
ROS 수업용 패키지 먼저 설치(리눅스 BSP 수업 이후 진행할 패키지 의존성때문에 먼저 설치)
13. ROS 메뉴얼 https://emanual.robotis.com/docs/en/platform/turtlebot3/quick-start/#pc-setup
설치 버전 Noetic
14.이메뉴얼 참고하여 설치
3.1.2 (Install ROS on Remote PC) 부터 설치 후 종료
15.VirtualBox -> 파일 -> 가상머신 내보내기
====================================================================================
(어제 인터넷 연결이 되지 않았던 이유) 우선 우리가 깐 리눅스 가상환경은 디폴트로 DHCP를 쓰고 있는데, 가상환경에 물려있는 DHCP 서버가 없어서 인터넷 연결이 안되었던 것이다.
(오늘 인터넷 연결이 된 이유)그래서 오늘 우리는 그 연결이 가능하도록 교수님이 공유기를 가져오셔서 DHCP 서버 셋팅을 해주신 것이다. (해당 공유기에는 10.10.15.100이라는 고정 아이피가 할당되어 있다.)
그런데 그걸 그냥 쓰면 우리 가상환경 상의 아이피 주소가 계속 바뀌어서 불편하다.(서버 프로그램을 짜서 구동했는데 아이피가 매번 바뀌면, 클라이언트쪽 프로그램에서 계속 아이피를 바꿔줘야 한다...)
그래서 그런 불편을 줄이기 위해 내부 아이피임에도 불구하고 고정아이피로 변경할 것이다. (우리 502호 강의실에 10.10.15.xx로 xx = 51~100까지 쓸수 있도록 되어있어서 고정아이피를 아껴써야 한다.)
- 윈도우IP: 10.10.15.64
- 가상환경 우분투IP: 10.10.15.84 (윈도우IP + 20)
- 라즈베리파이 유선IP: 10.10.15.164 (윈도우IP + 100)
- 라즈베리파이 무선IP: 10.10.15.215 (교수님 공유기 DHCP 자동할당)
- EOF 프로젝트용 와이파이모듈IP:
리눅스 네트워크 설정
해당 네트워크에 연결되어있는 호스트를 찾아가기 위해 필요한 것이었다.
원하는 아이피로 가기 위한 최적 경로를 찾기 위해 필요한 것이었다.
라우터의 성능이 너무 좋아서 UDP통신의 경우 요청 패킷보다 응답 패킷이 더 빨리 도착하는 문제가 발생해서, 통신 시퀀스를 맞춰줘야 하는 필요도 발생한다.(TCP통신의 경우 프로토콜 자체에서 ack을 체크하기 때문에 이런 문제는 없다.)
결과적으로 가상환경을 셋팅할 떄 "어탭터에 브릿지"를 설정해줌으로써 이제 외부IP에서도 가상환경 우분투 IP로 직접접근이 가능해진 것이다. 만약 "어탭터에 브릿지" 옵션 설정을 해주지 않았더라면, 윈도우와 가상환경 리눅스의 통신은 되더라도 외부IP와 리눅스의 통신은 되지 않았을 것이다.
공유기란 하나의 공인아이피를 받아와서 그것을 DHCP 기능을 통해서 여러개의 기기들이 공인아이피를 "공유"하도록 하는 것이다. 각각의 기기는 사설IP를 쓰게 되는 것이다. 실제로 외부 서버와 통신을 할 때는 모든 패킷이 DHCP 공유기를 통해서 공인아이피 주소로 외부에 나가게 되는 것이다.
아이피공유기도 일종의 훌륭한 임베디드 리눅스 시스템이다.
리눅스는 보통 서버용으로 많이 쓰는데, 리눅서 서버 터미널을 해당 머신에서 직접 사용하는것은 불편하다. 그리고 사실 리눅스를 서버로 쓸꺼면 리눅스를 desktop형태의 GUI로 설치할 필요가 없다. 서버용 리눅스는 그냥 윈도우기반 GUI 대신에 그냥 터미널만 뚱하니 뜨는 것만 쓰는 경우가 많다.
그래서 우리는 그러한 환경을 가정하고 윈도우에서 putty를 통해 원격으로 터미널에 접속하기 위해서 셋팅을 진행하겠다.
윈도우즈가 client가 되는 것이고, 리눅스 가상환경이 server가 되는 것이다.
우리의 목적은 리눅스 터미널 서버에 원격으로 접속하는 것이다.
가상환경 우분투에서 ssh server 패키지 설치
~$ sudo apt update
~$ sudo apt install openssh-server
윈도우즈에서 putty 설치
- SAMBA는 윈도우즈와 리눅스 간의 네트워크 파일시스템 공유 서버 프로토콜이다.
~$ sudo apt install samba -y //패키지 설치
~$ sudo mkdir /srv/samba //공유 디렉토리 setup
~$ sudo chmod 777 /srv/samba //디렉토리 접근권한 모두허용
~$ sudo vi /etc/samba/smb.conf //삼바 환경 설정
맨 끝에 아래 라인 추가
[samba]
comment = shared folder
path = /srv/samba
browseable = yes
writable = yes
valid users = ubuntu
public = yes
~$ sudo smbpasswd -a ubuntu //접속 계정과 암호 설정 (계정명:ubuntu/비번:ubuntu)
~$ sudo service smbd restart //삼바데몬 재시작
etc
윈도우즈 탐색기 실행창에서
\\10.10.15.84 //ubuntu IP
- NFS는 유닉스와 유닉스, 유닉스와 리눅스, 리눅스와 리눅스 간의 네트워크 파일 시스템 공유 서버 프로토콜이다.
ubuntu NFS 서버 설치
~$sudo apt-get install nfs-common nfs-kernel-server rpcbind
~$sudo mkdir /srv/nfs
~$sudo chmod 777 /srv/nfs
~$sudo vi /etc/exports
/srv/nfs 10.10.15.0/24(rw,sync)
~$sudo service nfs-kernel-server restart
~$sudo exportfs
/srv/nfs 10.10.15.0/24(rw,sync)
라즈베리파이에서 NFS 설치 및 마운트 (파일 읽고 쓰기)
~$sudo apt-get install nfs-common nfs-kernel-server rpcbind
~$sudo mkdir /mnt/ubuntu_nfs
~$sudo mount -t nfs 10.10.15.50:/srv/nfs /mnt/ubuntu_nfs //50:ubuntu서버 IP
~$df
...
10.10.15.50:/srv/nfs 78310400 5295104 69014016 8% /mnt/ubuntu_nfs
...
~$sudo cd /mnt/ubuntu_nfs ==> 10.10.15.50 서버의 /srv/nfs에 접속됨
NFS 마운트 해제
~$sudo umount /mnt/ubuntu_nfs
<현업에서 사용하는 임베디드쪽 MCU는 여전히 32bit인 것이 많다.>
4.디바이스 선택 : Raspberry pi 4
5.운영체제 선텍 ==> Raspberry Pi OS (32-bit) 선텍
6.저장소 선텍 ==> Mass Storage Device USB device - 31.9GB
Next --> 설정을 편집하기 --> GENERAL
hostname : pixx (xx : 01 ~ 25) *!!!나는 pi14로 설정
사용자 이름 및 비밀번호 설정 : 사용자 이름 : pi, 비밀번호 : raspberry
무선 LAN 설정 ssid : aiot5 ( aiot5)
비밀번호 : aiot5 + 0000 (aiot51234)
로케일 설정 체크
나머지는 수정 안함
SERVICES --> SSH 사용 (비밀번호 인증 사용) --> 이걸 꼭 해놔야 서비스 데몬으로 시작하자마자 ssh가 떠서 나중에 윈도우에서 putty로 접근할 수 있다.
ssh 사용 : 비밀번호 인증 사용 체크
저장 클릭 후
Use OS customization? 예 --> 데이터가 지워집니다 예 ==> 쓰는 중
이더넷케이블 허브와 라즈베리 연결
PC sd카드 제거 후 라즈베리파이 삽입 후 아답터 연결(부팅) - 1~2 분정도 기다림
윈도우 명령창에서 ping 명령으로 위에서 설정했던 hostname ping 테스트
ping pixx (xx : 01 ~ 23)
IP는 공유기 DHCP 할당된 IP 확인 후
putty로 라즈베리파이 연결
login : pi
passwd : raspberry
~$ ifconfig (이더넷과 wifi ip 확인)
라즈베리 파이 설정
$ sudo raspi-config
2 Display Options -> D3 VNC Resolution -> 1024x768
3 Interface Options -> I2 VNC -> enabled
5 Localisation Options -> L1 Locale --> [*] ko_KR.UTF-8 UTF-8 , Default Locale en_GB.UTF-8
-> L2 Timezone -> Asia Seoul
reboot
고정 IP 설정
real VNC로 접속 후 라즈비안OS GUI설정을 통해 ipv4 설정(고정 IP 설정)
putty 이더넷 주소로 접속
~$ ifconfig (이더넷과 wifi ip 확인)
한국 표준 시
$ date
한글 폰트 설치 후 웹브라우저 접속 확인
$ sudo apt update
$ sudo apt install ibus ibus-hangul fonts-unfonts-core fcitx fcitx-hangul
21.samba & nfs 설치
첨부 파일 참조
공유기 DHCP를 통해 할당되어, pi14에 잡힌 무선 아이피주소
10.10.15.215
라즈베리파이에도 우분투와 똑같이 삼바 설정을 해준다.
~$ sudo apt install samba -y //패키지 설치
~$ sudo mkdir /srv/samba //공유 디렉토리 setup
~$ sudo chmod 777 /srv/samba //디렉토리 접근권한 모두허용
~$ sudo vi /etc/samba/smb.conf //삼바 환경 설정
맨 끝에 아래 라인 추가
[samba]
comment = shared folder
path = /srv/samba
browseable = yes
writable = yes
valid users = pi
public = yes
~$ sudo smbpasswd -a pi //접속 계정과 암호 설정 (계정명:pi/비번:raspberry)
~$ sudo service smbd restart //삼바데몬 재시작
etc
윈도우즈 탐색기 실행창에서
\10.10.15.164 // raspberry pi IP
지금은 그냥 윈도우 탐색기에서 \10.10.15.164 를 쳐보면 "pi"라는 폴더명으로 파일시스템이 전부 노출되는 상황이다.
$ sudo vi /etc/samba/smb.conf
위 명령으로 설정파일 안에 진입해서 아래 이미지 사진부분을 찾아서, 주석이 빈 곳을 전부 주석으로 바꿔준다.
해당 부분에 주석이 빈 부분을 싹다 주석으로 바꿔줬다.
그리고 나서 삼바 데몬을 재시작해준다.
$ sudo service smbd restart
그리고 나서 윈도우 탐색기에서 다시 삼바로 라즈베리파이쪽 삼바에 접근하면 노출되었던 파일시스템 폴더가 사라진 것을 볼 수 있다.
우분투 가상환경에서 main.c를 컴파일 하여 만들어진 main실행파일에 대해서 아래 명령어를 치면 아래와 같은 파일 정보가 출력된다.
$ vi main.c
...
뭐라뭐라 파일 생성 후 저장
...
$ gcc main.c -o main
$ file main
main: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=dd79e77507ecc2fc6ea4c407c75d9110d0839846, for GNU/Linux 3.2.0, not stripped
ubuntu@ubuntu14:~$ ls -l main
-rwxrwxr-x 1 ubuntu ubuntu 16696 1월 31 14:53 main
ubuntu@ubuntu14:~$ strip main
ubuntu@ubuntu14:~$ ls -l main
-rwxrwxr-x 1 ubuntu ubuntu 14472 1월 31 15:16 main
ubuntu@ubuntu14:~$ file main
main: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=dd79e77507ecc2fc6ea4c407c75d9110d0839846, for GNU/Linux 3.2.0, stripped
배포하기 전에는 스트립 한번을 해주고 하는게 관례다. 스트립을 하면 파일 크기도 줄어든다. 그러면 맨 마지막에 not stripped였던 것이 stripped로 바뀐 것을 알 수 있다. 스트립 되었다는 것은 파일에 관련된 추가정보를 제거하고 오로지 '실행에 필요한 정보만 남겨두었다'는 뜻이다.
라즈베리파이 환경에서 동일한 작업을 반복해보자.
그러면 ARM용으로 파일이 생성되는 것을 알 수 있다.
pi@pi14:~ $ file main
main: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=f752316057b578e2fe81257fa5d398453db4550f, for GNU/Linux 3.2.0, not stripped
윈도우 탐색기 쌈바를 거쳐서 우분투 가상환경 파일을 라즈베리파이로 전송하는것은 너무나 번거로운 작업이다. 이것을 한방에 해결해주는 것이 scp 명령어이다.
(scp는 ssh를 설치할 때 딸려온 명령어이다.)
ubuntu@ubuntu14:~$ scp main.c pi@10.10.15.164:~
The authenticity of host '10.10.15.164 (10.10.15.164)' can't be established.
ECDSA key fingerprint is SHA256:/V/RtqWon/MnCHB6hk18+Xne6LaQTZKPW0rPDGoTOEc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.15.164' (ECDSA) to the list of known hosts.
pi@10.10.15.164's password:
main.c 100% 14KB 4.0MB/s 00:00
ubuntu@ubuntu14:~$
우분투 가상환경에 교차개발환경에 많이 쓰는 툴체인을 설치하겠다.
$ sudo apt-get install gawk git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python-setuptools python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev xterm rsync curl zstd lz4 bison flex // 의존성 패키지
$ sudo apt install crossbuild-essential-armhf //arm 32bit 툴체인 설치
전부 설치하면 이제 타겟보드용 컴파일을 테스트해보자.
$ gcc main.c -o main_x86 // 인텔용
$ arm-linux-gnueabihf-gcc main.c -o main_arm // 그냥 gcc 앞에다가 "arm-linux-gnueabinf-"라는 접두어를 붙여주면 arm용 실행파일을 만들게 된다.
이렇게 우분투 가상환경에서 만들어진 두개의 실행파일을 spc로 라즈베리파이에 전송시켜서 동작을 확인해보자. 당연히 arm 기계어로 cross compile된 파일만 실행이 된다.
$ scp main_x86 pi@10.10.15.164:~
$ scp main_arm pi@10.10.15.164:~
가상환경 우분투(linux)와 라즈베리파이 라즈비안(linux) 사이에 파일공유 시스템을 설정하면 불필요하게 samba를 세네번 걸치면서 계속 복사하는 작업은 오버헤드가 너무 크다.
그래서 '마운트'개념을 사용하여 네트워크 상의 다른 유저의 파일시스템을 마치 나의 파일시스템인것 마냥 접근하여 사용하겠다는 것이다.
1. 내 우분투 가상환경의 하드 공간(server)을 라즈베리파이(client)에서 접근하여 사용
2. 교수님의 우분투 가상환경의 하드 공간(server)을 우리의 우분투 가상환경(client)에서 접근하여 사용
우리의 가상환경 우분투에 NFS를 설치하여 교수님 우분투 파일시스템에 직접 마운트 하여 마치 내 폴더인것 마냥 접근하여 사용할 수 있다는 것이다. (내 우분투 가상환경과 내 라즈베리파이의 nfs 관계도 마찬가지)
~$sudo apt-get install nfs-common nfs-kernel-server rpcbind
~$sudo mkdir /srv/nfs
~$sudo chmod 777 /srv/nfs
~$sudo vi /etc/exports
-----------------------
/srv/nfs 10.10.15.0/24(rw,sync)
-----------------------
~$sudo service nfs-kernel-server restart
~$sudo exportfs
/srv/nfs 10.10.15.0/24(rw,sync)
~$sudo apt-get install nfs-common nfs-kernel-server rpcbind
~$sudo mkdir /mnt/ubuntu_nfs
~$sudo mount -t nfs 10.10.15.84:/srv/nfs /mnt/ubuntu_nfs //84:ubuntu서버 IP
~$df
-------------
10.10.15.84:/srv/nfs 78310400 5295104 69014016 8% /mnt/ubuntu_nfs
-------------
~$sudo cd /mnt/ubuntu_nfs ==> 10.10.15.84 서버의 /srv/nfs에 접속됨
이로써 라즈베리파이에서 우분투의 /srv/nfs 경로에 있는 부분의 하드디스크를 네트워크를 통해 마치 자신의 디렉토리인냥 쓸 수 있게 되었다.
pi@pi14:/mnt/ubuntu_nfs $ cat /etc/fstab
proc /proc proc defaults 0 0
PARTUUID=f729bde1-01 /boot/firmware vfat defaults 0 2
PARTUUID=f729bde1-02 / ext4 defaults,noatime 0 1
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that
아래는 교수님으로부터 지급받은 "nfs마운트.sh(=nfs.sh)"의 소스파일이다.
#!/bin/bash
#vi ~/.profile
#if [ -f /mnt/nfs.sh ] ; then
# . /mnt/nfs.sh
#fi
SERVIP=10.10.141.30
if ! df | grep lect_nfs > /dev/null ; then
ping -c 1 $SERVIP > /dev/null
if [ $? -eq 0 ] ; then
sudo mount -t nfs $SERVIP:/srv/nfs /mnt/lect_nfs
df | grep lect_nfs
fi
fi
그냥 위 소스파일은 참고하라고 복붙해놓은 것이다.
위 파일에서 가장 핵심적인 부분은 "sudo mount -t nfs $SERVIP:/srv/nfs /mnt/lect_nfs" 명령어 부분이다.
"nfs마운트.sh" 파일을 samba를 통해 라즈베리파이로 가져오고, 그 파일을 라즈베리파이의 "/mnt" 경로로 이동시킨다.
$ vi nfs.sh
그리고 ~/.profile 파일을 수정해줘서 라즈베리파이가 실행될 때 자동으로 마운트가 발생하도록 쉘 스크립트에 실행라인을 추가해준다.
$ vi ~/.profile
// 맨 아래다가 아래 세줄을 추가
if [ -f /mnt/nfs.sh ] ; then
. /mnt/nfs.sh
fi
이로써 우리는 라즈베리파이를 부팅할 때마다 자동으로 nfs가 마운팅 되도록 설정되었다.
~$ sudo umount /mnt/ubuntu_nfs
~$ /mnt/nfs.sh
또는
~$ sudo mount -t nfs 10.10.15.84:/srv/nfs /mnt/ubuntu_nfs
결국은 편리한 cross compile 개발환경을 셋팅하기 위해, 네트워크를 통한 파일시스템 공유 기능을 사용하겠다는 것이다.
마운트는 리눅스쪽에서만 쓰는 용어이다.
하지만 큰 줄기는 같다.
SAMBA나 SCP나 NFS MOUNT나 결국 목표로 하는 것은 같다는 것이다.
"네트워크를 통한 파일시스템 공유"
멋져요~