Microsoft MVP성태의 닷넷 이야기
개발 환경 구성: 722. ARM 플랫폼 빌드를 위한 미니 PC(?) - Khadas VIM4 [링크 복사], [링크+제목 복사],
조회: 2073
글쓴 사람
정성태 (seongtaejeong at gmail.com)
홈페이지
첨부 파일
 

(시리즈 글이 4개 있습니다.)
개발 환경 구성: 722. ARM 플랫폼 빌드를 위한 미니 PC(?) - Khadas VIM4
; https://www.sysnet.pe.kr/2/0/13727

개발 환경 구성: 724. ARM + docker 환경에서 .NET 8 설치
; https://www.sysnet.pe.kr/2/0/13732

개발 환경 구성: 726. ARM 플랫폼용 Visual C++ 리눅스 프로젝트 빌드
; https://www.sysnet.pe.kr/2/0/13735

C/C++: 176. C/C++ - ARM64로 포팅할 때 유의할 점
; https://www.sysnet.pe.kr/2/0/13751




ARM 플랫폼 빌드를 위한 미니 PC(?) - Khadas VIM4

C++ 모듈을 그동안 x64 플랫폼의 Windows, Linux 환경으로 빌드하다가 ARM 빌드까지 필요하게 됐습니다. 딱히, 어떤 서비스를 위한 것은 아니고, 오직 빌드와 간단한 테스트 정도만 요구되는 것이라 고성능(그러니까 고가)의 장비가 필요한 것은 아니었는데요, 그래서 서버 장비가 아닌 일반 PC급으로 알아봤습니다.

그런데, 의외로 ARM CPU를 장착한 PC가 없었습니다. 반면 노트북 제품은 좀 있었는데요, 가령 이번에 나온 Surface 랩탑 7 세대(Copilot+PC) 같은 경우가 있습니다. 물론, 이 제품은 ARM 빌드를 위한 용도치고는 좀 고가입니다. ^^

그래서, 아예 보드로 타깃을 변경했는데요, 그중에서 아래의 제품을 선택했습니다.

쿨링팬 + 히트 싱크 + 카다스 Khadas VIM4 미니PC 산업용 초소형 싱글 보드 컴퓨터 라즈베리파이 완벽 대체 스틱PC
; https://www.icbanq.com/P014186500

khadas_vim4_1.png

나름 과거에 라즈베리파이나 아두이노 계열의 보드를 사용해 본 경험이 있어서 그런지 그리 낯설게 느껴지지는 않았습니다. 게다가 "산업용"이라는 표현이 있어서 왠지 고장이 잘 안 날 것 같은 느낌이 들었습니다. ^^;

일단, 위의 제품은 "보드"만 포함돼 있어서 mini PC처럼 구성하려면 부가적인 제품을 더 구매해야 합니다. 일례로, HDMI 케이블을 전용으로 구매해야 하는데요,

Khadas HDMI Cable 카다스용 케이블 초소형 커넥터 헤드
; https://www.icbanq.com/P014008252

왜냐하면, 일반 HDMI 케이블도 보드에 꽂을 수는 있지만 폭이 넓어서, 인접해 있는 USB-C 타입의 전원 케이블을 연결할 수가 없습니다. (억지로 끼우면 연결은 되는데 약간 비틀어지기 때문에 불안합니다.)

그리고, 당연히 전원 어댑터가 필요한데요,

24W USB-C Adapter
; https://www.khadas.com/product-page/usb-c-24w-adapter

Khadas 공식 홈페이지에서 제공하는 제품으로, PDO 규격에 다음의 출력을 지원합니다.

USB Power Delivery Output: 5V at 3A, 9V at 2.67A, or 12V at 2A

이와 비슷한 제품으로 쿠팡에서 다음의 제품을 검색했는데요,

삼성전자 C to C 타입 25W 고속 충전기 EP-TA800
; https://www.coupang.com/vp/products/6927354136?itemId=16750725117

PDO - 5.0V 3.0A or 9.0V 2.77A

다행히 icbanq 측에 문의를 해보니 저 어댑터로도 사용이 가능하다는 답변을 받아 추가 구매를 했습니다.




자, 그래서 키보드 및 모니터를 연결하고 전원을 넣으면 VIM4에 내장된 OS가 부팅이 되는데요, 전용 OS(OOWOW)가 미리 설치돼 있어 인터넷만 연결돼 있다면 곧바로 Ubuntu 24.04를 설치할 수 있습니다.

그렇게 Ubuntu가 설치됐다면 이후 작업은 일반적인 PC와 동일합니다. 우선 먼저 해야 할 것이 새로운 사용자를 추가한 후,

$ sudo useradd -m kevin
$ sudo passwd kevin
New password:
Retype new password:
passwd: password updated successfully

해당 사용자를 root 권한으로 바꾸고 보안을 위해 (Khahdas VIM4의 기본 사용자인) khadas 사용자를 비활성화합니다.

# usermod -L -e 1 khadas

다시 로그인을 한 다음, 편의상 bash shell로 변경합니다.

$ source
-sh: 4: source: not found

$ chsh --shell /bin/bash kevin
Password:

그다음은... 아무래도 유선 랜보다는 무선이 더 편할 것이므로 와이파이도 함께 설정합니다.

$ nmcli d
DEVICE         TYPE      STATE         CONNECTION
wlan0          wifi      disconnected  --
wlan1          wifi      disconnected  --
eth0           ethernet  unavailable   --
dummy0         dummy     unmanaged     --
lo             loopback  unmanaged     --
p2p-dev-wlan0  wifi-p2p  unmanaged     --
p2p-dev-wlan1  wifi-p2p  unmanaged     --

$ sudo nmcli r wifi on

$ nmcli d wifi list
IN-USE  BSSID              SSID          MODE   CHAN  RATE        SIGNAL  BARS  SECURITY
        F6:9F:B2:2C:06:1C  TESTSSID      Infra  161   405 Mbit/s  40      ▂▄__  WPA2
        FA:9F:B2:2A:06:1C  --            Infra  11    405 Mbit/s  19      ▂___  WPA2

$ sudo nmcli d wifi connect TESTSSID password 

혹시 유선 랜의 경우 고정 IP를 설정하고 싶다면,

How To Configure Static IP Address In Ubuntu 22.04 (Easy Guide)
; https://ostechnix.com/configure-static-ip-address-ubuntu/

netplan 설정 파일을 백업한 다음,

$ ls /etc/netplan/
90-NM-1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3.yaml  fenix-default.yaml

$ sudo cp /etc/netplan/90-NM-1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3.yaml /etc/netplan/90-NM-1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3.yaml_backup.yaml

90-NM-1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3.yaml 파일을 편집해 eth0 어댑터에 고정 IP 주소를 추가합니다.

$ sudo cat /etc/netplan/90-NM-1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3.yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      addresses:
        - 192.168.0.70/24
      routes:
        - to: default
          via: 192.168.0.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
  wifis:
    NM-1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3:
      renderer: NetworkManager
      match:
        name: "wlan0"
      dhcp4: true
      dhcp6: true
      access-points:
        "TESTSSID":
          auth:
            key-management: "psk"
            password: "test_pass_word"
          networkmanager:
            uuid: "1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3"
            name: "TESTSSID"
            passthrough:
              wifi-security.auth-alg: "open"
              ipv6.addr-gen-mode: "default"
              ipv6.ip6-privacy: "-1"
              proxy._: ""
      networkmanager:
        uuid: "1ed2165d-a1e4-33e1-b46e-bc7ea3d60fa3"
        name: "TESTSSID"

그다음 변경 사항을 적용해 주면 끝!

$ sudo netplan try




다음으로 시간 설정을 해야 하는데요, 기본적으로 ntp 서버는 잘 잡혀 있고 데몬도 작동 중입니다.

$ cat /etc/chrony/chrony.conf | grep pool
# - 2 sources from 2.ubuntu.pool.ntp.org which is ipv6 enabled as well
# - 1 source from [01].ubuntu.pool.ntp.org each (ipv4 only atm)
# See http://www.pool.ntp.org/join.html for more information.
pool ntp.ubuntu.com        iburst maxsources 4
pool 0.ubuntu.pool.ntp.org iburst maxsources 1
pool 1.ubuntu.pool.ntp.org iburst maxsources 1
pool 2.ubuntu.pool.ntp.org iburst maxsources 2

단지 시간대가 맞지 않는데요,

// How to Set or Change the Time Zone in Linux
// https://linuxize.com/post/how-to-set-or-change-timezone-in-linux/

$ timedatectl
               Local time: Mon 2024-09-02 12:52:24 UTC
           Universal time: Mon 2024-09-02 12:52:24 UTC
                 RTC time: Mon 2024-09-02 12:52:25
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

이것만 Asia/Seoul로 변경하면 됩니다.

$ timedatectl list-timezones | grep Seoul
Asia/Seoul

$ sudo timedatectl set-timezone Asia/Seoul

$ timedatectl
               Local time: Mon 2024-09-02 21:54:18 KST
           Universal time: Mon 2024-09-02 12:54:18 UTC
                 RTC time: Mon 2024-09-02 12:54:19
                Time zone: Asia/Seoul (KST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no




Wake-On-Lan(WOL) 설정도 하면 좋을 것입니다. 단지, WOL 설정은 리눅스 운영체제에서 할 수는 없고 OOWOW OS에서 해야 합니다. 그래서 그 운영체제로 다시 부팅을 해야 하는데요, 방법은 보드의 Function 키를 누른 채로 Reset 버튼을 누르면 됩니다.

이후 OOWOW로 부팅이 됐으면 WOL 관련 메뉴로 들어가 활성화시킨 후 다시 Ubuntu로 부팅하면 됩니다. 정상적으로 설정이 되었다면 다음과 같이 WOL 옵션이 나올 것입니다.

$ sudo ethtool eth0
Settings for eth0:
        Supported ports: [ TP    MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Link partner advertised link modes:  10baseT/Half 10baseT/Full
                                             100baseT/Half 100baseT/Full
        Link partner advertised pause frame use: Symmetric
        Link partner advertised auto-negotiation: Yes
        Link partner advertised FEC modes: Not reported
        Speed: 100Mb/s
        Duplex: Full
        Auto-negotiation: on
        master-slave cfg: preferred slave
        master-slave status: slave
        Port: Twisted Pair
        PHYAD: 0
        Transceiver: external
        MDI-X: Unknown
        Supports Wake-on: ug
        Wake-on: d
        Current message level: 0x0000003f (63)
                               drv probe link timer ifdown ifup
        Link detected: yes

이후 시스템을 shutdown 시키는 시간을 스케줄로 등록해 두면 되고,

Schedule a Shutdown in Linux Command Line
; https://linuxhandbook.com/schedule-shutdown/

$  sudo crontab -e
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/mcedit

$ sudo cat /var/spool/cron/crontabs/root
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.fp3ro9/crontab installed on Sun Sep  1 23:44:58 2024)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
# Edit this file to introduce tasks to be run by cron.
#
# ...[생략]...
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

50 17 * * * /usr/sbin/shutdown now

위의 경우는 오후 5시 50분에 시스템을 종료하도록 설정했습니다. 반대로 시스템을 깨우는 것은 WOL 프로그램을 사용하시면 되는데요, 마침 예전에 만들어 둔,

C# - WOL(Wake On Lan) 구현
; https://www.sysnet.pe.kr/2/0/12336

프로그램을 (별도 윈도우 환경의) Task Scheduler에 등록했습니다. (물론, 잘 동작합니다.)




마지막으로, SSH 로그인을 매번 비밀번호를 입력하는 것이 불편하니, 공개키를 등록해 주면 편리할 것입니다. %USERPROFILE%/.ssh에 생성해 두었던 (혹은 새롭게 생성한) 공개키 파일을 복사해 VIM4의 ~/.ssh/authorized_keys 파일에 붙여 넣으면 됩니다.

// $HOME 디렉터리 하위에 .ssh 디렉터리를 만들고,
$ chmod 700 ~/.ssh

// authorized_keys 이름의 파일을 만들어 그 안에 공개키를 붙여 넣습니다.
$ cat ~/tmp.pub >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

ssh까지 됐으면 사실상 모니터는 필요 없으므로 HDMI 케이블을 빼도 됩니다. (즉, 1회용에 불과한 HDMI 케이블을 구매해야 하는 것이 아쉽긴 합니다.)




제 경우에는 빌드용으로 구매했지만, 나름 GPIO 포트도 있어 원한다면 재미있는 IoT 프로젝트도 할 수 있을 것입니다. 게다가 OOWOW 화면에서 OTG 기능을 지원하는 것도 메뉴에 있었는데요,

Khadas VIM4 Review
; https://www.hackster.io/idreams/khadas-vim4-review-03e3ef

위의 스펙 내용에도 "USB2.0 OTG"가 있는 것으로 보아 USB 장치로써 동작시키는 것도 가능할 듯합니다. 그렇다면 (해보진 않았지만) 아마 가상 키보드 등으로 사용하는 것도 가능할 것입니다.

Raspberry Pi Zero(OTG)를 다른 컴퓨터에 연결해 가상 키보드로 쓰는 방법
; https://www.sysnet.pe.kr/2/0/11354

이와 관련해 Q&A를 보면 리눅스 OS 빌드가 필요한 듯합니다. ^^

How to get USB OTG port to work in Device mode?
; https://forum.khadas.com/t/how-to-get-usb-otg-port-to-work-in-device-mode/166




기타 부가 장치 소개를 해볼까요? 필요하다면 스크린도 구매할만합니다.

Khadas TS050 Touch Screen (K-TS-001)
; https://www.icbanq.com/P014007435

그리고 케이스도 있으면 좋을 것입니다.

Khadas DIY Case 2 (KCS-B-002) 
; https://www.icbanq.com/P016112255

저도 케이스는 구매했는데요, 나사 조립까지 하고 싶다면 아주 작은 십자드라이버를 별도로 구매해야 합니다. 다행히 케이스가 접합시키는 부분이 있어서 그것만 닫히면 쉽게 열리지 않아 나사 조립까지는 안 했습니다.

그리고, 만약 모니터가 DP 전용이라면 HDMI to DP 변환기도 필요할 텐데요,

넥스트 HDMI to 디스플레이 포트 변환 아답터 NEXT-2420HDP
; https://www.coupang.com/vp/products/37000618?itemId=136267417&vendorItemId=3291696081

저처럼 실수하실 분들이 계실까 봐 미리 말씀드리면 저런 변환기는 구매하시면 안 됩니다. 왜냐하면, HDMI 단자를 보드에 먼저 연결하는 방식인데 (위에서 설명했듯이) 이것 역시 단자의 크기가 커서 인접한 USB-C 단자를 사용할 수 없습니다. 따라서 구매해야 한다면, 위에서 구매했던 HDMI 케이블을 입력으로 꽂을 수 있고 DP 단자를 모니터에 연결할 수 있는 제품을 선택하셔야 합니다.




그나저나, 예전에 ARM 개발을 위한 Windows Dev Kit 2023을 마이크로소프트에서 판매한 적이 있습니다.

Windows Dev Kit 2023
; https://www.microsoft.com/en-us/d/windows-dev-kit-2023/94k0p67w7581?activetab=pivot:overviewtab

600 달러(한화 약 80만 원) 정도면 나름 괜찮은 가격대인데요, 아쉽게도 국내에는 발매가 안됐습니다. 그러다 최근에, "Windows Dev Center" 사이트에 "Snapdragon Dev Kit for Windows"에 대한 새로운 소식이 있어 링크를 눌렀더니 "Join the Future of Windows Development with Snapdragon" 신청 페이지가 열렸습니다.

Join the Future of Windows Development with Snapdragon
; https://www.qualcomm.com/support/contact/forms/snapdragon-developer-kit

일단 신청은 해두었는데, 글쎄요, 국내까지 판매를 해줄지는 모르겠습니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 9/7/2024]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2024-09-07 12시56분
Creating Docker multi-arch images for ARM64 from Windows
; https://andrewlock.net/creating-multi-arch-docker-images-for-arm64-from-windows/

Combining multiple docker images into a multi-arch image
; https://andrewlock.net/combining-multiple-docker-images-into-a-multi-arch-image/
정성태

[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13765정성태10/12/2024248오류 유형: 928. go build 시 "package maps is not in GOROOT" 오류
13764정성태10/11/2024209Linux: 85. Ubuntu - 원하는 golang 버전 설치
13763정성태10/11/2024219Linux: 84. WSL / Ubuntu 20.04 - bpftool 설치
13762정성태10/11/2024202Linux: 83. WSL / Ubuntu 22.04 - bpftool 설치
13761정성태10/11/2024209오류 유형: 927. WSL / Ubuntu - /usr/include/linux/types.h:5:10: fatal error: 'asm/types.h' file not found
13760정성태10/11/2024232Linux: 82. Ubuntu - clang 최신(stable) 버전 설치
13759정성태10/10/2024422C/C++: 177. C++ - 자유 함수(free function) 및 주소 지정 가능한 함수(addressable function)
13758정성태10/8/2024591오류 유형: 926. dotnet tools를 sudo로 실행하는 경우 command not found
13757정성태10/8/2024329닷넷: 2306. Linux - dotnet tool의 설치 디렉터리가 PATH 환경변수에 자동 등록이 되는 이유
13756정성태10/8/2024354오류 유형: 925. ssh로 docker 접근을 할 때 "... malformed HTTP status code ..." 오류 발생
13755정성태10/7/2024636닷넷: 2305. C# 13 - (9) 메서드 바인딩의 우선순위를 지정하는 OverloadResolutionPriority 특성 도입 (Overload resolution priority)파일 다운로드1
13754정성태10/4/2024693닷넷: 2304. C# 13 - (8) 부분 메서드 정의를 속성 및 인덱서에도 확대파일 다운로드1
13753정성태10/4/2024727Linux: 81. Linux - PATH 환경변수의 적용 규칙
13752정성태10/2/2024793닷넷: 2303. C# 13 - (7) ref struct의 interface 상속 및 제네릭 제약으로 사용 가능파일 다운로드1
13751정성태10/2/2024836C/C++: 176. C/C++ - ARM64로 포팅할 때 유의할 점
13750정성태10/1/2024849C/C++: 175. C++ - WinMain/wWinMain 호출 전의 CRT 초기화 단계
13749정성태9/30/20241037닷넷: 2302. C# - ssh-keygen으로 생성한 Private Key와 Public Key 연동파일 다운로드1
13748정성태9/29/20241124닷넷: 2301. C# - BigInteger 타입이 byte 배열로 직렬화하는 방식
13747정성태9/28/20241014닷넷: 2300. C# - OpenSSH의 공개키 파일에 대한 "BEGIN OPENSSH PUBLIC KEY" / "END OPENSSH PUBLIC KEY" PEM 포맷파일 다운로드1
13746정성태9/28/2024996오류 유형: 924. Python - LocalProtocolError("Illegal header value ...")
13745정성태9/28/20241022Linux: 80. 리눅스 - 실행 중인 프로세스 내부의 환경변수 설정을 구하는 방법 (lldb)
13744정성태9/27/20241102닷넷: 2299. C# - Windows Hello 사용자 인증 다이얼로그 표시하기파일 다운로드1
13743정성태9/26/20241354닷넷: 2298. C# - Console 프로젝트에서의 await 대상으로 Main 스레드 활용하는 방법 [1]
13742정성태9/26/20241065닷넷: 2297. C# - ssh-keygen으로 생성한 ecdsa 유형의 Public Key 파일 해석 [1]파일 다운로드1
13741정성태9/25/2024945디버깅 기술: 202. windbg - ASP.NET MVC Web Application (.NET Framework) 응용 프로그램의 덤프 분석 시 요령
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...