리눅스 실행
작업중인 커널을 다운로드하는 대신 기존 커널 소스를 재사용해 커널을 해킹한 후 개발 용으로 테스트 한다.
최소한의 리눅스 이미지 사용.
설치
sudo apt-get install git qemu
sudo apt-get build-dep busybox linux-image-$(uname -r)
mkdir -p ~/bin
cd ~/bin
git clone --recursive https://github.com/cirosantilli/runlinux
echo 'PATH="$PATH:'$(pwd)'/runlinux"' >> ~/.bashrc
. ~/.bashrc
예제
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.2
runlinux
처음 부팅시 시간이 걸린다.
부팅 되면 커널 소스를 해킹
runlinux
사용자 정의 구성 외부 트리 빌드:
export KBUILD_OUTPUT="$(pwd)/../build"
make menuconfig
runlinux
기존 구성 파이리이 없으면 KBUILD_OUTPUT, make defconfig 사용.
QEMU 추가 옵션 설정.
runlinux -- -bios ~/path/to/OVMF.fd
bios 대신 UEFI x64 사용시 다운로드.
https://sourceforge.net/projects/edk2/files/OVMF/OVMF-X64-r15214.zip
실 하드웨어 실행
빌드 디렉토리에 main.img 파일 생성:
runlinux -i
usb 장치 연결
sudo lsblk
sudo fdisk -l
usb 이미지 굽기
sudo dd if=main.img of=/dev/sdx
실제 컴퓨터 바이오스 부팅 시퀀서 USB 변경
이미지 동작 확인.
qemu-system-x86_64 -enable-kvm -hda main.img
선택사항
사용자 정의 initrd 생성
n
BysyBox 무시 한 후 사용자정의 루트파일 시스템 사용.
runlinux -n /path/to/my/directory/
runlinux -n /path/to/my/init
경로 설정:
- 디렉토리 압축
리눅스 부팅시 가장 먼저 /init 디렉토리를 찾아 실행함.
- init 파일을 사용하면 압축된 파일 시스템의 루트 이름이 바뀜.
initrd 참고: https://nautiluslee.blogspot.com/2019/01/init-hello-world.html
GDB 커널 디버깅:
../runlinux/runlinux -g
CONFIG_DEBUG_INFO 필요한 경우, 커널 옵션을 설정한 후 커널 다시 빌드.
QEMU를 실행 후 GDB 활성화.
디버깅 준비 예:
hbreak start_kernel
list
continue
카테고리
asm
(27)
bootloader_x86_grub
(1)
C
(92)
compile
(11)
config
(76)
CPP
(13)
CSS
(1)
debugging
(7)
gimp
(1)
Go
(1)
html
(1)
Java
(1)
JavaScript
(1)
kernel
(19)
LibreOffice
(3)
Linux system progamming
(21)
MFC
(1)
opencv
(4)
OpenGL
(1)
PHP
(1)
Python
(4)
qemu
(29)
shell
(3)
socket
(7)
troubleshooting
(2)
ubuntu18.04
(2)
windows
(1)
2019/01/05
init hello world 프로그램
init hello world 프로그램
init.S 추가
.global _start
_start:
mov $1, %rax
mov $1, %rdi
mov $message, %rsi
mov $message_len, %rdx
syscall
jmp .
message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
.equ message_len, . - message
종료 시스템 호출 및 커널 패닉 사용할 수 없을 때:
mkdir d
as --64 -o init.o init.S # assemble
ld -o d/init init.o # link
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
hello world 정보를 가진 init 파일 시스템 생성.
커널 소스 다운로드
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
QEMU 실행
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"
메세지 확인
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
C 프로그램 사용.
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
컴파일
gcc -static init.c -o init
usb 부팅 실 하드웨어 테스트
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
init.S 추가
.global _start
_start:
mov $1, %rax
mov $1, %rdi
mov $message, %rsi
mov $message_len, %rdx
syscall
jmp .
message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
.equ message_len, . - message
종료 시스템 호출 및 커널 패닉 사용할 수 없을 때:
mkdir d
as --64 -o init.o init.S # assemble
ld -o d/init init.o # link
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
hello world 정보를 가진 init 파일 시스템 생성.
커널 소스 다운로드
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
QEMU 실행
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"
메세지 확인
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
C 프로그램 사용.
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
컴파일
gcc -static init.c -o init
usb 부팅 실 하드웨어 테스트
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
GDB 커널 단계별 디버깅
GDB 단계별 디버깅
리눅스 커널 디버깅
./run -d
start_kernel 부트 시퀀스와 같은 심볼에서 직접 접근
./rungdb start_kernel
QEMU 정지, GDB 명령어 사용 활성화:
l
n
c
부팅 건너 뛰려면 다음 실행.
./rungdb
gdm 모드 정지 ctrl + c
QEMU 내부 스크립트 테스트
./count.sh
stdout 무한대 계산, GDB 다음과 같이 계산됨.
Ctrl + C
break sys_write
continue
continue
continue
커널 모듈 디버깅
./run -d
./rungdb
QEMU 모드 진입:
insmod /fops.ko
정지 CTRL + C
scanning for modules in ../kernel_module-1.0/
loading @0xffffffffa0000000: ../kernel_module-1.0//fops.ko
간단한 심볼
b fop_write
c
QEMU 모드 진입:
printf a >/sys/kernel/debug/lkmc_fops/f
GDB 브레이크 포인트 fop_write 지정
rmmod 하기 전 브레이크 포인트 해제, 그렇지 않으면 브레이크 포이트 정보 가지고 있음.
하드코어 방식의 디버깅, 별로 사용하지 않는 방식
insmod /fops.ko
cat /proc/modules
fops 2327 0 - Live 0xfffffffa00000000
모듈로드 정보 GDB 전달
Ctrl + C
add-symbol-file ../kernel_module-1.0/fops.ko 0xfffffffa00000000
커널 초기 디버그 부팅
./rungdb extract_kernel
./rungdb main
리눅스 커널 디버깅
./run -d
start_kernel 부트 시퀀스와 같은 심볼에서 직접 접근
./rungdb start_kernel
QEMU 정지, GDB 명령어 사용 활성화:
l
n
c
부팅 건너 뛰려면 다음 실행.
./rungdb
gdm 모드 정지 ctrl + c
QEMU 내부 스크립트 테스트
./count.sh
stdout 무한대 계산, GDB 다음과 같이 계산됨.
Ctrl + C
break sys_write
continue
continue
continue
커널 모듈 디버깅
./run -d
./rungdb
QEMU 모드 진입:
insmod /fops.ko
정지 CTRL + C
scanning for modules in ../kernel_module-1.0/
loading @0xffffffffa0000000: ../kernel_module-1.0//fops.ko
간단한 심볼
b fop_write
c
QEMU 모드 진입:
printf a >/sys/kernel/debug/lkmc_fops/f
GDB 브레이크 포인트 fop_write 지정
rmmod 하기 전 브레이크 포인트 해제, 그렇지 않으면 브레이크 포이트 정보 가지고 있음.
하드코어 방식의 디버깅, 별로 사용하지 않는 방식
insmod /fops.ko
cat /proc/modules
fops 2327 0 - Live 0xfffffffa00000000
모듈로드 정보 GDB 전달
Ctrl + C
add-symbol-file ../kernel_module-1.0/fops.ko 0xfffffffa00000000
커널 초기 디버그 부팅
./rungdb extract_kernel
./rungdb main
qemu 스냅 샷
스냅샷 생성
QEMU 원본 이미지를 참조하는 이미지 생성.
기존 이미지 스탭 샵을 만든 후 다음 버전의 스냅샷으로 작업을 진행하는 이미지 원리.
-b : 백업
qemu-img create -f qcow2 -b centos-cleaninstall.img snapshot.img
이전 버전 돌아가기
변경된 스탭 샷 이미지는 원래 상태로 되돌릴 수 없다.
대신 첫 번째 스냅 샷 이미지를 생성하고, 그 이미지 파일을 사용한다.
백업 파일 수정
$ qemu-img info snapshot.img
임시 스탭 샵.
qemu -hda centos-cleaninstall.img -snapshot
QEMU 원본 이미지를 참조하는 이미지 생성.
기존 이미지 스탭 샵을 만든 후 다음 버전의 스냅샷으로 작업을 진행하는 이미지 원리.
-b : 백업
qemu-img create -f qcow2 -b centos-cleaninstall.img snapshot.img
이전 버전 돌아가기
변경된 스탭 샷 이미지는 원래 상태로 되돌릴 수 없다.
대신 첫 번째 스냅 샷 이미지를 생성하고, 그 이미지 파일을 사용한다.
백업 파일 수정
$ qemu-img info snapshot.img
임시 스탭 샵.
qemu -hda centos-cleaninstall.img -snapshot
우분투 18.04 qemu 호스트/게스트 설정
우분투 18.04 qemu 호스트/게스트 설정
wget http://releases.ubuntu.com/18.04/ubuntu-18.04.1-desktop-amd64.iso
qemu-img create -f qcow2 ubuntu-18.04-desktop-amd64.img.qcow2 64G
qemu-system-x86_64 \
-cdrom ubuntu-18.04-desktop-amd64.iso \
-drive file=ubuntu-18.04-desktop-amd64.img.qcow2,format=qcow2 \
-enable-kvm \
-m 2G \
-smp 2 \
-vga virtio \
;
GUI 에서 우분투 설치
기본 버전 이미지 생성(초기 버전)
qemu-img create -f qcow2 -b ubuntu-18.04-desktop-amd64.img.qcow2 \
ubuntu-18.04-desktop-amd64.snapshot.qcow2
시스템 다시 시작.
qemu-system-x86_64 \
-drive file=ubuntu-18.04-desktop-amd64.snapshot.qcow2,format=qcow2 \
-enable-kvm \
-m 2G \
-smp 2 \
-soundhw hda \
-vga virtio \
;
설치부터 다시 할 경우 실행
qemu-img create -f qcow2 -b ubuntu-18.04-desktop-amd64.img.qcow2 \
ubuntu-18.04-desktop-amd64.snapshot.qcow2
스냅 샷은 원본 이미지 사이의 차이점만 저장하기 때문에 디스크 공간을 많이 차지하지 않음
해상도 설정 옵션
-vga virtio
전체 화면 사용
-full-screen
Ctrl + Alt + F
QEMU 기본 비활성화
-soundhw hda
부팅 시간 단축 및 부팅 메시지 표시
printf 'GRUB_TIMEOUT=1\nGRUB_CMDLINE_LINUX_DEFAULT=""\n' | sudo tee -a /etc/default/grub
sudo update-grub
접속
1. virt-manager에 spice-gtk 클라이언트가 내장됨.
vm 호스트에서 python-spice-client-gtk 설치.
virt-manager를 사용하여 다른 호스트에서 ssh를 통해 VM 호스트에 원격으로 연결하는 경우 해당 시스템에 python-spice-client-gtk도 설치해야함.
2. virt-manager 시작
3. 가상화 컴퓨터 시작
4. 가상화 컴퓨터 전원 ON
5. ssh 게스트 연결, 게스트에서 spice-vdagent 설치하고 spice-vdagentd 시작 되었는 지 확인
6. 가상환경 하드웨어 세부 정보 표시
7. Display VNC 선택하고 VNC를 Spice 변경한 후 수락해 채널 추가
8. Cirrus(기본값)에서 QXL 비디오 모델 변경
9. virt-manager 다시 시작하고 가상 시스템 전원을 켠다.
x 값 없을때 해결방법(단 호스트환경에서 VM으로 ssh 접근 할 수 있다는 전제 조건)
~$ssh user@host
~$ssh user@guest
설치
프로젝트 사이트: https://www.spice-space.org/download.html
sudo apt install spice-vdagent
설정 방법.
https://wiki.archlinux.org/index.php/QEMU#SPICE
https://www.linux-kvm.org/page/SPICE
시도,
-spice port=5930,disable-ticketing+ remote-viewer spice://127.0.0.1:5930, 그리고 spice-vdagent 게스트 설치, 성공하지 못함.
근본 원인은 QEMU devs 안정적 구현하지 않음, QEMU 개발 방법은 비대화 형 개발에 더 중점을 둔다.
참고:
호스트 3D 가속. SPICE 및 QXL을 glxgears사용하는 경우 1k FPS를 제공하고 일반 SDL과 동리 함.
호스트에서 __GL_SYNC_TO_VBLANK=0 vblank_mode=0 glxgears20k FPS를 제공하므로 그래픽이 가속되지 않은 것으로 보임.
wget http://releases.ubuntu.com/18.04/ubuntu-18.04.1-desktop-amd64.iso
qemu-img create -f qcow2 ubuntu-18.04-desktop-amd64.img.qcow2 64G
qemu-system-x86_64 \
-cdrom ubuntu-18.04-desktop-amd64.iso \
-drive file=ubuntu-18.04-desktop-amd64.img.qcow2,format=qcow2 \
-enable-kvm \
-m 2G \
-smp 2 \
-vga virtio \
;
GUI 에서 우분투 설치
기본 버전 이미지 생성(초기 버전)
qemu-img create -f qcow2 -b ubuntu-18.04-desktop-amd64.img.qcow2 \
ubuntu-18.04-desktop-amd64.snapshot.qcow2
시스템 다시 시작.
qemu-system-x86_64 \
-drive file=ubuntu-18.04-desktop-amd64.snapshot.qcow2,format=qcow2 \
-enable-kvm \
-m 2G \
-smp 2 \
-soundhw hda \
-vga virtio \
;
설치부터 다시 할 경우 실행
qemu-img create -f qcow2 -b ubuntu-18.04-desktop-amd64.img.qcow2 \
ubuntu-18.04-desktop-amd64.snapshot.qcow2
스냅 샷은 원본 이미지 사이의 차이점만 저장하기 때문에 디스크 공간을 많이 차지하지 않음
해상도 설정 옵션
-vga virtio
전체 화면 사용
-full-screen
Ctrl + Alt + F
QEMU 기본 비활성화
-soundhw hda
부팅 시간 단축 및 부팅 메시지 표시
printf 'GRUB_TIMEOUT=1\nGRUB_CMDLINE_LINUX_DEFAULT=""\n' | sudo tee -a /etc/default/grub
sudo update-grub
접속
1. virt-manager에 spice-gtk 클라이언트가 내장됨.
vm 호스트에서 python-spice-client-gtk 설치.
virt-manager를 사용하여 다른 호스트에서 ssh를 통해 VM 호스트에 원격으로 연결하는 경우 해당 시스템에 python-spice-client-gtk도 설치해야함.
2. virt-manager 시작
3. 가상화 컴퓨터 시작
4. 가상화 컴퓨터 전원 ON
5. ssh 게스트 연결, 게스트에서 spice-vdagent 설치하고 spice-vdagentd 시작 되었는 지 확인
6. 가상환경 하드웨어 세부 정보 표시
7. Display VNC 선택하고 VNC를 Spice 변경한 후 수락해 채널 추가
8. Cirrus(기본값)에서 QXL 비디오 모델 변경
9. virt-manager 다시 시작하고 가상 시스템 전원을 켠다.
x 값 없을때 해결방법(단 호스트환경에서 VM으로 ssh 접근 할 수 있다는 전제 조건)
~$ssh user@host
~$ssh user@guest
설치
프로젝트 사이트: https://www.spice-space.org/download.html
sudo apt install spice-vdagent
설정 방법.
https://wiki.archlinux.org/index.php/QEMU#SPICE
https://www.linux-kvm.org/page/SPICE
시도,
-spice port=5930,disable-ticketing+ remote-viewer spice://127.0.0.1:5930, 그리고 spice-vdagent 게스트 설치, 성공하지 못함.
근본 원인은 QEMU devs 안정적 구현하지 않음, QEMU 개발 방법은 비대화 형 개발에 더 중점을 둔다.
참고:
호스트 3D 가속. SPICE 및 QXL을 glxgears사용하는 경우 1k FPS를 제공하고 일반 SDL과 동리 함.
호스트에서 __GL_SYNC_TO_VBLANK=0 vblank_mode=0 glxgears20k FPS를 제공하므로 그래픽이 가속되지 않은 것으로 보임.
node.js 버전별 관리 프로젝트
프로젝트 사이트
https://github.com/creationix/nvm
다운로드
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | sh
source ~/.nvm/nvm.sh
nvm install --lts
nvm use --lts
npm install --global vaca
vaca
bashrc 추가.
f="$HOME/.nvm/nvm.sh"
if [ -r "$f" ]; then
. "$f" &>'/dev/null'
nvm use --lts &>'/dev/null'
fi
장점:
sudo 없이 Node 버전 사용
가능한 바이너리 파일을 설치
버전별 전환 방법
nvm install 0.9.0
nvm install 0.9.9
nvm use 0.9.0
node --version
#v0.9.0
nvm use 0.9.9
node --version
#v0.9.9
https://github.com/creationix/nvm
다운로드
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | sh
source ~/.nvm/nvm.sh
nvm install --lts
nvm use --lts
npm install --global vaca
vaca
bashrc 추가.
f="$HOME/.nvm/nvm.sh"
if [ -r "$f" ]; then
. "$f" &>'/dev/null'
nvm use --lts &>'/dev/null'
fi
장점:
sudo 없이 Node 버전 사용
가능한 바이너리 파일을 설치
버전별 전환 방법
nvm install 0.9.0
nvm install 0.9.9
nvm use 0.9.0
node --version
#v0.9.0
nvm use 0.9.9
node --version
#v0.9.9
debootstrap_x86 qemu 자동 설치 스크립트
#!/usr/bin/env bash
set -eux
suite=xenial
debootstrap_dir=$suite
img_file=${suite}.ext4.img
kernel=/vmlinuz
initrd=/initrd.img
sudo apt install -y \
debootstrap \
qemu-system-x86 \
;
if [ ! -d "$debootstrap_dir" ]; then
# Create debootstrap directory.
sudo debootstrap \
"$suite" \
"$debootstrap_dir" \
http://archive.ubuntu.com/ubuntu \
;
# Set root password.
echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd
# Remount root filesystem as rw.
cat << EOF | sudo tee "$debootstrap_dir/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF
# Automaticaly start networking.
# Otherwise network commands fail with:
# Temporary failure in name resolution
# https://gist.github.com/corvax19/6230283#gistcomment-1940694
cat << EOF | sudo tee "$debootstrap_dir/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q
[Install]
WantedBy=multi-user.target
EOF
sudo ln -sf /etc/systemd/system/dhclient.service \
"${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"
fi
if [ ! -f "$img_file" ]; then
# Create disk image
dd if=/dev/null of="$img_file" bs=1M seek=2048
mkfs.ext4 "$img_file"
mnt_dir="${suite}_mnt"
mkdir "$mnt_dir"
sudo mount -t ext4 "$img_file" "$mnt_dir"
sudo cp -r "$debootstrap_dir/." "$mnt_dir"
sudo umount "$mnt_dir"
rmdir "$mnt_dir"
fi
sudo qemu-system-x86_64 \
-append 'console=ttyS0 root=/dev/sda' \
-drive "file=${img_file},format=raw" \
-enable-kvm \
-nographic \
-serial mon:stdio \
-m 2G \
-kernel "$kernel" \
-initrd "$initrd" \
;
set -eux
suite=xenial
debootstrap_dir=$suite
img_file=${suite}.ext4.img
kernel=/vmlinuz
initrd=/initrd.img
sudo apt install -y \
debootstrap \
qemu-system-x86 \
;
if [ ! -d "$debootstrap_dir" ]; then
# Create debootstrap directory.
sudo debootstrap \
"$suite" \
"$debootstrap_dir" \
http://archive.ubuntu.com/ubuntu \
;
# Set root password.
echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd
# Remount root filesystem as rw.
cat << EOF | sudo tee "$debootstrap_dir/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF
# Automaticaly start networking.
# Otherwise network commands fail with:
# Temporary failure in name resolution
# https://gist.github.com/corvax19/6230283#gistcomment-1940694
cat << EOF | sudo tee "$debootstrap_dir/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q
[Install]
WantedBy=multi-user.target
EOF
sudo ln -sf /etc/systemd/system/dhclient.service \
"${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"
fi
if [ ! -f "$img_file" ]; then
# Create disk image
dd if=/dev/null of="$img_file" bs=1M seek=2048
mkfs.ext4 "$img_file"
mnt_dir="${suite}_mnt"
mkdir "$mnt_dir"
sudo mount -t ext4 "$img_file" "$mnt_dir"
sudo cp -r "$debootstrap_dir/." "$mnt_dir"
sudo umount "$mnt_dir"
rmdir "$mnt_dir"
fi
sudo qemu-system-x86_64 \
-append 'console=ttyS0 root=/dev/sda' \
-drive "file=${img_file},format=raw" \
-enable-kvm \
-nographic \
-serial mon:stdio \
-m 2G \
-kernel "$kernel" \
-initrd "$initrd" \
;
2019/01/04
debootstrap arm64 qemu 설치
debootstrap arm64
1)
-- foreign 패키지 다운로드.
-- chroot 사용
-- --second-stage + QEMU 사용자 모드 에물레이션 사용.(binfmt_misc)
2) 커널 vfs 패닉
[ 0.773665] Please append a correct "root=" boot option; here are the available partitions:
[ 0.774033] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
파일 시스템 지원 확인.
CONFIG_VIRTIO_BLK=y
initrd에서 모듈이 로드되어야 하기 때문에 ISO 이미지를 사용해서 동작 시켜야 할 듯 함.
다른 유형의 파일시스템 유형을 사용하려고 시도했지만 커널 지원 문제가 있어, 커널 컴파일을 해야함.
-drive if= -M virt
데비안 계열 우분투 패키지 커널을 사용할 때 arm64 커널 빌드 명령어.
처음 빌드 시
export ARCH=arm64
export $(dpkg-architecture -aarm64); export CROSS_COMPILE=aarch64-linux-gnu-
fakeroot debian/rules clean
debian/rules build
fakeroot debian/rules binary
두번째 이상 빌드시.
rm debian/stamps/stamp-build*
debian/rules build
fakeroot debian/rules binary
커널 설정 옵션에서 개발자 모드를 활성화.
Ubuntu devs, CONFIG y
인터넷 동작 문제.
systemctl status dhclient.service
cat f
자동 설치 스크립트
#!/usr/bin/env bash
# https://askubuntu.com/questions/281763/is-there-any-prebuilt-qemu-ubuntu-image32bit-online/1081171#1081171
set -eux
debootstrap_dir=debootstrap
root_filesystem=debootstrap.ext2.qcow2
sudo apt-get install \
gcc-aarch64-linux-gnu \
debootstrap \
libguestfs-tools \
qemu-system-aarch64 \
qemu-user-static \
;
if [ ! -d "$debootstrap_dir" ]; then
sudo debootstrap \
--arch arm64 \
--foreign \
bionic \
"$debootstrap_dir" \
http://ports.ubuntu.com/ubuntu-ports \
;
sudo mkdir -p "${debootstrap_dir}/usr/bin"
sudo cp "$(which qemu-aarch64-static)" "${debootstrap_dir}/usr/bin"
sudo chroot "$debootstrap_dir" /debootstrap/debootstrap --second-stage
sudo rm -f "$root_filesystem"
fi
linux_image="$(printf "${debootstrap_dir}/boot/vmlinuz-"*)"
if [ ! -f "$root_filesystem" ]; then
# Set root password.
echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd
# Remount root filesystem as rw.
cat << EOF | sudo tee "${debootstrap_dir}/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF
# https://askubuntu.com/questions/1045278/ubuntu-server-18-04-temporary-failure-in-name-resolution/1080902#1080902
cat << EOF | sudo tee "${debootstrap_dir}/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q
[Install]
WantedBy=multi-user.target
EOF
sudo ln -sf "${debootstrap_dir}/etc/systemd/system/dhclient.service" \
"${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"
# https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725
sudo chmod +r "${linux_image}"
# Generate image file from debootstrap directory.
# Leave 1Gb extra empty space in the image.
sudo virt-make-fs \
--format qcow2 \
--size +1G \
--type ext2 \
"$debootstrap_dir" \
"$root_filesystem" \
;
sudo chmod 666 "$root_filesystem"
fi
# 커널 컴파일.
linux_image="$(pwd)/linux/debian/build/build-generic/arch/arm64/boot/Image"
if [ ! -f "$linux_image" ]; then
#git clone --branch Ubuntu-4.15.0-20.21 --depth 1 git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git linux
cd linux
cat << EOF | patch -p1
diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu
index 5ff32cb997e9..8a190d3a0299 100644
--- a/debian.master/config/config.common.ubuntu
+++ b/debian.master/config/config.common.ubuntu
@@ -10153,7 +10153,7 @@ CONFIG_VIDEO_ZORAN_ZR36060=m
CONFIG_VIPERBOARD_ADC=m
CONFIG_VIRTIO=y
CONFIG_VIRTIO_BALLOON=y
-CONFIG_VIRTIO_BLK=m
+CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_BLK_SCSI=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_VIRTIO_INPUT=m
EOF
export ARCH=arm64
export $(dpkg-architecture -aarm64)
export CROSS_COMPILE=aarch64-linux-gnu-
fakeroot debian/rules clean
debian/rules updateconfigs
fakeroot debian/rules DEB_BUILD_OPTIONS=parallel=`nproc` build-generic
cd -
fi
#linux_image=/home/ciro/bak/git/linux-kernel-module-cheat/out/linux/default/aarch64/arch/arm64/boot/Image
#linux_image=/home/ciro/bak/git/linux-kernel-module-cheat/submodules/linux/debian/build/build-generic/arch/arm64/boot/Image
qemu-system-aarch64 \
-append 'console=ttyAMA0 root=/dev/vda rootfstype=ext2' \
-device rtl8139,netdev=net0 \
-drive "file=${root_filesystem},format=qcow2" \
-kernel "${linux_image}" \
-m 2G \
-netdev user,id=net0 \
-serial mon:stdio \
-M virt,highmem=off \
-cpu cortex-a57 \
-nographic \
;
1)
-- foreign 패키지 다운로드.
-- chroot 사용
-- --second-stage + QEMU 사용자 모드 에물레이션 사용.(binfmt_misc)
2) 커널 vfs 패닉
[ 0.773665] Please append a correct "root=" boot option; here are the available partitions:
[ 0.774033] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
파일 시스템 지원 확인.
CONFIG_VIRTIO_BLK=y
initrd에서 모듈이 로드되어야 하기 때문에 ISO 이미지를 사용해서 동작 시켜야 할 듯 함.
다른 유형의 파일시스템 유형을 사용하려고 시도했지만 커널 지원 문제가 있어, 커널 컴파일을 해야함.
-drive if= -M virt
데비안 계열 우분투 패키지 커널을 사용할 때 arm64 커널 빌드 명령어.
처음 빌드 시
export ARCH=arm64
export $(dpkg-architecture -aarm64); export CROSS_COMPILE=aarch64-linux-gnu-
fakeroot debian/rules clean
debian/rules build
fakeroot debian/rules binary
두번째 이상 빌드시.
rm debian/stamps/stamp-build*
debian/rules build
fakeroot debian/rules binary
커널 설정 옵션에서 개발자 모드를 활성화.
Ubuntu devs, CONFIG y
인터넷 동작 문제.
systemctl status dhclient.service
cat f
자동 설치 스크립트
#!/usr/bin/env bash
# https://askubuntu.com/questions/281763/is-there-any-prebuilt-qemu-ubuntu-image32bit-online/1081171#1081171
set -eux
debootstrap_dir=debootstrap
root_filesystem=debootstrap.ext2.qcow2
sudo apt-get install \
gcc-aarch64-linux-gnu \
debootstrap \
libguestfs-tools \
qemu-system-aarch64 \
qemu-user-static \
;
if [ ! -d "$debootstrap_dir" ]; then
sudo debootstrap \
--arch arm64 \
--foreign \
bionic \
"$debootstrap_dir" \
http://ports.ubuntu.com/ubuntu-ports \
;
sudo mkdir -p "${debootstrap_dir}/usr/bin"
sudo cp "$(which qemu-aarch64-static)" "${debootstrap_dir}/usr/bin"
sudo chroot "$debootstrap_dir" /debootstrap/debootstrap --second-stage
sudo rm -f "$root_filesystem"
fi
linux_image="$(printf "${debootstrap_dir}/boot/vmlinuz-"*)"
if [ ! -f "$root_filesystem" ]; then
# Set root password.
echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd
# Remount root filesystem as rw.
cat << EOF | sudo tee "${debootstrap_dir}/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF
# https://askubuntu.com/questions/1045278/ubuntu-server-18-04-temporary-failure-in-name-resolution/1080902#1080902
cat << EOF | sudo tee "${debootstrap_dir}/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q
[Install]
WantedBy=multi-user.target
EOF
sudo ln -sf "${debootstrap_dir}/etc/systemd/system/dhclient.service" \
"${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"
# https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725
sudo chmod +r "${linux_image}"
# Generate image file from debootstrap directory.
# Leave 1Gb extra empty space in the image.
sudo virt-make-fs \
--format qcow2 \
--size +1G \
--type ext2 \
"$debootstrap_dir" \
"$root_filesystem" \
;
sudo chmod 666 "$root_filesystem"
fi
# 커널 컴파일.
linux_image="$(pwd)/linux/debian/build/build-generic/arch/arm64/boot/Image"
if [ ! -f "$linux_image" ]; then
#git clone --branch Ubuntu-4.15.0-20.21 --depth 1 git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git linux
cd linux
cat << EOF | patch -p1
diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu
index 5ff32cb997e9..8a190d3a0299 100644
--- a/debian.master/config/config.common.ubuntu
+++ b/debian.master/config/config.common.ubuntu
@@ -10153,7 +10153,7 @@ CONFIG_VIDEO_ZORAN_ZR36060=m
CONFIG_VIPERBOARD_ADC=m
CONFIG_VIRTIO=y
CONFIG_VIRTIO_BALLOON=y
-CONFIG_VIRTIO_BLK=m
+CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_BLK_SCSI=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_VIRTIO_INPUT=m
EOF
export ARCH=arm64
export $(dpkg-architecture -aarm64)
export CROSS_COMPILE=aarch64-linux-gnu-
fakeroot debian/rules clean
debian/rules updateconfigs
fakeroot debian/rules DEB_BUILD_OPTIONS=parallel=`nproc` build-generic
cd -
fi
#linux_image=/home/ciro/bak/git/linux-kernel-module-cheat/out/linux/default/aarch64/arch/arm64/boot/Image
#linux_image=/home/ciro/bak/git/linux-kernel-module-cheat/submodules/linux/debian/build/build-generic/arch/arm64/boot/Image
qemu-system-aarch64 \
-append 'console=ttyAMA0 root=/dev/vda rootfstype=ext2' \
-device rtl8139,netdev=net0 \
-drive "file=${root_filesystem},format=qcow2" \
-kernel "${linux_image}" \
-m 2G \
-netdev user,id=net0 \
-serial mon:stdio \
-M virt,highmem=off \
-cpu cortex-a57 \
-nographic \
;
Linux 커널 exec의 시스템 호출 ELF 방식에서 스크립트 언어 #! 인식 shebang 지정.
Linux 커널 exec의 시스템 호출 #! 인식 shebang 지정.
#! 사람이 읽기 편하도록 구성한다는 의미(스크립트 언어)
./something
리눅스 커널 소스
linux/fs/binfmt_script.c
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
바이트를 읽은 후 비교.
참이면 커널에서 파싱.
경로 /usr/bin/env python 첫 번째 인수 사용하여 또 다른 exec 호출 생성.
/usr/bin/env python /path/to/script.py
#주석 문자 사용하는 모든 스크립팅 언어에서 동작 함.
무한 루프도 만들 수 있음.
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
bash 오류 인식
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
ELF 실행 파일
linux/fs/binfmt_elf.c
magic.elfmag[EI_MAG0] = ELFMAG0;
바이트 검사. 7f 45 4c 46, 사람이 읽을 수 있으나 이해 하려면 시간이 걸림.
EFL 형식의 파일을 읽고, 메모리에 정확하게 넣고, 새로운 프로세스 시작.
#! 사람이 읽기 편하도록 구성한다는 의미(스크립트 언어)
./something
리눅스 커널 소스
linux/fs/binfmt_script.c
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
바이트를 읽은 후 비교.
참이면 커널에서 파싱.
경로 /usr/bin/env python 첫 번째 인수 사용하여 또 다른 exec 호출 생성.
/usr/bin/env python /path/to/script.py
#주석 문자 사용하는 모든 스크립팅 언어에서 동작 함.
무한 루프도 만들 수 있음.
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
bash 오류 인식
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
ELF 실행 파일
linux/fs/binfmt_elf.c
magic.elfmag[EI_MAG0] = ELFMAG0;
바이트 검사. 7f 45 4c 46, 사람이 읽을 수 있으나 이해 하려면 시간이 걸림.
EFL 형식의 파일을 읽고, 메모리에 정확하게 넣고, 새로운 프로세스 시작.
debootstrap이란?
debootstrap이란?
x86 시스템에서 임베디드 ARM 또는 PowerPC 시스템용 데비안/우분투를 설치를 의미, 조금더 큰 의미에서는 네트워 부팅도 여기에 속 할 수 있음, 요즘 클라우드 컴퓨팅 환경 구성이 과도기를 지나 완성도를 높이는 단계로 진입한 듯 함.
1. .deb 패키지 파일을 다운로드 받아 압축해제.
2. qemu-user-static 에물레이트 하기 위해 모든 패키지 구성 스크립트 실행
간단한 사용 예제.
우분투 18.04
sudo apt-get install \
debootstrap \
qemu-user-static \
;
debootstrap_dir=debootstrap
sudo debootstrap \
--arch arm64 \
--foreign \
bionic \
"$debootstrap_dir" \
http://ports.ubuntu.com/ubuntu-ports \
;
sudo mkdir -p "${debootstrap_dir}/usr/bin"
sudo cp "$(which qemu-aarch64-static)" "${debootstrap_dir}/usr/bin"
sudo chroot "$debootstrap_dir" /debootstrap/debootstrap --second-stage
sudo rm -f "$root_filesystem"
x86 시스템에서 임베디드 ARM 또는 PowerPC 시스템용 데비안/우분투를 설치를 의미, 조금더 큰 의미에서는 네트워 부팅도 여기에 속 할 수 있음, 요즘 클라우드 컴퓨팅 환경 구성이 과도기를 지나 완성도를 높이는 단계로 진입한 듯 함.
1. .deb 패키지 파일을 다운로드 받아 압축해제.
2. qemu-user-static 에물레이트 하기 위해 모든 패키지 구성 스크립트 실행
간단한 사용 예제.
우분투 18.04
sudo apt-get install \
debootstrap \
qemu-user-static \
;
debootstrap_dir=debootstrap
sudo debootstrap \
--arch arm64 \
--foreign \
bionic \
"$debootstrap_dir" \
http://ports.ubuntu.com/ubuntu-ports \
;
sudo mkdir -p "${debootstrap_dir}/usr/bin"
sudo cp "$(which qemu-aarch64-static)" "${debootstrap_dir}/usr/bin"
sudo chroot "$debootstrap_dir" /debootstrap/debootstrap --second-stage
sudo rm -f "$root_filesystem"
리눅스 커널 컴파일 init/main.c 부팅시 메세지 출력
init/main.c
커널 소스 다운로드
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git
cd ubuntu-bionic
# 작업할 커널 소스버전 변경.
git checkout Ubuntu-4.15.0-20.21
fakeroot debian/rules clean
debian/rules updateconfigs
fakeroot debian/rules build-generic
linux_image="$(pwd)/debian/build/build-generic/arch/x86_64/boot/bzImage"
커널 정보 추출 확인.
https://nautiluslee.blogspot.com/2019/01/config.html
패치 적용
diff --git a/init/main.c b/init/main.c
index b8b121c17ff1..542229349efc 100644
--- a/init/main.c
+++ b/init/main.c
@@ -516,6 +516,8 @@ asmlinkage __visible void __init start_kernel(void)
char *command_line;
char *after_dashes;
+ pr_info("I'VE Hae Nam Korea Linux Love man!!!");
+
set_task_stack_end_magic(&init_task);
smp_setup_processor_id();
debug_objects_early_init();
빌드
fakeroot debian/rules build-generic
부팅 메시지 출력
I'VE Hae Nam Korea Linux Love man
Kernel: arch/x86/boot/bzImage is ready (#3)
커널 소스 다운로드
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git
cd ubuntu-bionic
# 작업할 커널 소스버전 변경.
git checkout Ubuntu-4.15.0-20.21
fakeroot debian/rules clean
debian/rules updateconfigs
fakeroot debian/rules build-generic
linux_image="$(pwd)/debian/build/build-generic/arch/x86_64/boot/bzImage"
커널 정보 추출 확인.
https://nautiluslee.blogspot.com/2019/01/config.html
패치 적용
diff --git a/init/main.c b/init/main.c
index b8b121c17ff1..542229349efc 100644
--- a/init/main.c
+++ b/init/main.c
@@ -516,6 +516,8 @@ asmlinkage __visible void __init start_kernel(void)
char *command_line;
char *after_dashes;
+ pr_info("I'VE Hae Nam Korea Linux Love man!!!");
+
set_task_stack_end_magic(&init_task);
smp_setup_processor_id();
debug_objects_early_init();
빌드
fakeroot debian/rules build-generic
부팅 메시지 출력
I'VE Hae Nam Korea Linux Love man
Kernel: arch/x86/boot/bzImage is ready (#3)
우분투 커널 .config 환경 설정 부분 확인 및 추출 방법.
우분투 커널 .config 파일 관련
우분투 git 커널 저장소
debian/config 커널 트리 메타 데이터 git 저장소
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/
우분투 18.04 linux-image-4.15.0-36-generici 커널 패키지에 대한 태크 정보는 Ubuntu-4.15.0-36.39.
config 파일 저장소
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/tree/debian.master/config?h=Ubuntu-4.15.0-36.39
config.common.ubuntu, config.common.amd64, config.flavour.generic 병합 linux-image-4.15.0-36-generic 커널 패키지가 나옴.
병합하는 스크립트
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/tree/debian/scripts/misc/kernelconfig?h=Ubuntu-4.15.0-36.39
# Merge configs
# We merge config.common.ubuntu + config.common.<arch> +
# config.flavour.<flavour>
아키텍쳐 별 구성 파일.
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/tree/debian.master/config/annotations?h=Ubuntu-4.15.0-36.39
환경 설정없이 컴파일
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git linux
cd linux
git checkout Ubuntu-4.15.0-36.39
fakeroot debian/rules clean
debian/rules updateconfigs
fakeroot debian/rules build-generic
현재 커널 설정 내용과 차이점 비교.
diff debian/build/build-generic/.config /boot/config-4.15.0-36-generic
.deb 파일 구성
최종 커널 환경 설정 값
/boot/config-4.15.0-36-generic
커널 이미지
/boot/vmlinuz-4.15.0-36-generic
패키지 버전 확인
dpkg -S /boot/config-4.15.0-36-generic
패키지 파일은 다음 내용을 제공 함.
linux-modules-4.15.0-36-generic: /boot/config-4.15.0-36-generic
패키지 정보 목록 확인
https://packages.ubuntu.com/bionic-updates/linux-modules-4.15.0-36-generic
환경 구성 파일 추출
mkdir config
cd config
wget http://mirrors.kernel.org/ubuntu/pool/main/l/linux/linux-modules-4.15.0-36-generic_4.15.0-36.39_amd64.deb
ar x linux-modules-4.15.0-36-generic_4.15.0-36.39_amd64.deb
tar -xvf data.tar.xz
cat ./boot/config-4.15.0-36-generic
우분투 git 커널 저장소
debian/config 커널 트리 메타 데이터 git 저장소
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/
우분투 18.04 linux-image-4.15.0-36-generici 커널 패키지에 대한 태크 정보는 Ubuntu-4.15.0-36.39.
config 파일 저장소
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/tree/debian.master/config?h=Ubuntu-4.15.0-36.39
config.common.ubuntu, config.common.amd64, config.flavour.generic 병합 linux-image-4.15.0-36-generic 커널 패키지가 나옴.
병합하는 스크립트
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/tree/debian/scripts/misc/kernelconfig?h=Ubuntu-4.15.0-36.39
# Merge configs
# We merge config.common.ubuntu + config.common.<arch> +
# config.flavour.<flavour>
아키텍쳐 별 구성 파일.
https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/tree/debian.master/config/annotations?h=Ubuntu-4.15.0-36.39
환경 설정없이 컴파일
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git linux
cd linux
git checkout Ubuntu-4.15.0-36.39
fakeroot debian/rules clean
debian/rules updateconfigs
fakeroot debian/rules build-generic
현재 커널 설정 내용과 차이점 비교.
diff debian/build/build-generic/.config /boot/config-4.15.0-36-generic
.deb 파일 구성
최종 커널 환경 설정 값
/boot/config-4.15.0-36-generic
커널 이미지
/boot/vmlinuz-4.15.0-36-generic
패키지 버전 확인
dpkg -S /boot/config-4.15.0-36-generic
패키지 파일은 다음 내용을 제공 함.
linux-modules-4.15.0-36-generic: /boot/config-4.15.0-36-generic
패키지 정보 목록 확인
https://packages.ubuntu.com/bionic-updates/linux-modules-4.15.0-36-generic
환경 구성 파일 추출
mkdir config
cd config
wget http://mirrors.kernel.org/ubuntu/pool/main/l/linux/linux-modules-4.15.0-36-generic_4.15.0-36.39_amd64.deb
ar x linux-modules-4.15.0-36-generic_4.15.0-36.39_amd64.deb
tar -xvf data.tar.xz
cat ./boot/config-4.15.0-36-generic
debootstrap amd64 전체 이미지 파일 구성 qemu
debootstrap amd64
모든 패키지 다운로드 구성
#!/usr/bin/env bash
# https://askubuntu.com/questions/281763/is-there-any-prebuilt-qemu-ubuntu-image32bit-online/1081171#1081171
set -eux
debootstrap_dir=debootstrap
root_filesystem=debootstrap.ext2.qcow2
sudo apt-get install \
debootstrap \
libguestfs-tools \
qemu-system-x86 \
;
if [ ! -d "$debootstrap_dir" ]; then
# Create 디렉토리 생성.
# - linux-image-generic: /boot 사용할 커널 이미지 다운로드
# - network-manager: 부팅시 네트워크 사용
sudo debootstrap \
--include linux-image-generic \
bionic \
"$debootstrap_dir" \
http://archive.ubuntu.com/ubuntu \
;
sudo rm -f "$root_filesystem"
fi
linux_image="$(printf "${debootstrap_dir}/boot/vmlinuz-"*)"
if [ ! -f "$root_filesystem" ]; then
# Set root password.
echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd
# 루투 파일시스템 rw 모드로 마운팅.
cat << EOF | sudo tee "${debootstrap_dir}/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF
# 네트워크 시작.
# 네트워크 명령어 입력 실패시 :
# 일시적 실패....
# https://askubuntu.com/questions/1045278/ubuntu-server-18-04-temporary-failure-in-name-resolution/1080902#1080902
cat << EOF | sudo tee "$debootstrap_dir/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q
[Install]
WantedBy=multi-user.target
EOF
sudo ln -sf "$debootstrap_dir/etc/systemd/system/dhclient.service" \
"${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"
# https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725
sudo chmod +r "${linux_image}"
# debootstrap 디렉토리에 이미지 파일 생성.
# 1Gb 공간 남겨둔.
sudo virt-make-fs \
--format qcow2 \
--size +1G \
--type ext2 \
"$debootstrap_dir" \
"$root_filesystem" \
;
sudo chmod 666 "$root_filesystem"
fi
qemu-system-x86_64 \
-append 'console=ttyS0 root=/dev/sda' \
-drive "file=${root_filesystem},format=qcow2" \
-enable-kvm \
-serial mon:stdio \
-m 2G \
-kernel "${linux_image}" \
-device rtl8139,netdev=net0 \
-netdev user,id=net0 \
;
login: root
pw: root
인터넷 동작 확인
wget그리고 curl기본적으로 설치되지 않기 때문에 다음 명령어로 인터넷 동작 확인
ping 또한 qemu에서 기본적으로 동작 하지 않음.
printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' | nc example.com 80
apt-get update
apt-get install hello
hello
모든 패키지 다운로드 구성
#!/usr/bin/env bash
# https://askubuntu.com/questions/281763/is-there-any-prebuilt-qemu-ubuntu-image32bit-online/1081171#1081171
set -eux
debootstrap_dir=debootstrap
root_filesystem=debootstrap.ext2.qcow2
sudo apt-get install \
debootstrap \
libguestfs-tools \
qemu-system-x86 \
;
if [ ! -d "$debootstrap_dir" ]; then
# Create 디렉토리 생성.
# - linux-image-generic: /boot 사용할 커널 이미지 다운로드
# - network-manager: 부팅시 네트워크 사용
sudo debootstrap \
--include linux-image-generic \
bionic \
"$debootstrap_dir" \
http://archive.ubuntu.com/ubuntu \
;
sudo rm -f "$root_filesystem"
fi
linux_image="$(printf "${debootstrap_dir}/boot/vmlinuz-"*)"
if [ ! -f "$root_filesystem" ]; then
# Set root password.
echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd
# 루투 파일시스템 rw 모드로 마운팅.
cat << EOF | sudo tee "${debootstrap_dir}/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF
# 네트워크 시작.
# 네트워크 명령어 입력 실패시 :
# 일시적 실패....
# https://askubuntu.com/questions/1045278/ubuntu-server-18-04-temporary-failure-in-name-resolution/1080902#1080902
cat << EOF | sudo tee "$debootstrap_dir/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q
[Install]
WantedBy=multi-user.target
EOF
sudo ln -sf "$debootstrap_dir/etc/systemd/system/dhclient.service" \
"${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"
# https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725
sudo chmod +r "${linux_image}"
# debootstrap 디렉토리에 이미지 파일 생성.
# 1Gb 공간 남겨둔.
sudo virt-make-fs \
--format qcow2 \
--size +1G \
--type ext2 \
"$debootstrap_dir" \
"$root_filesystem" \
;
sudo chmod 666 "$root_filesystem"
fi
qemu-system-x86_64 \
-append 'console=ttyS0 root=/dev/sda' \
-drive "file=${root_filesystem},format=qcow2" \
-enable-kvm \
-serial mon:stdio \
-m 2G \
-kernel "${linux_image}" \
-device rtl8139,netdev=net0 \
-netdev user,id=net0 \
;
login: root
pw: root
인터넷 동작 확인
wget그리고 curl기본적으로 설치되지 않기 때문에 다음 명령어로 인터넷 동작 확인
ping 또한 qemu에서 기본적으로 동작 하지 않음.
printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' | nc example.com 80
apt-get update
apt-get install hello
hello
UEFI Cloud image arm64
UEFI Cloud image arm64
sudo apt-get install qemu-efi
자동 스크립트
vi uefi_cloud_image.sh
#!/usr/bin/env bash
set -eux
#sudo apt-get install cloud-image-utils qemu-system-arm qemu-efi
# 이미지 다운로드.
img=ubuntu-18.04-server-cloudimg-arm64.img
if [ ! -f "$img" ]; then
wget "https://cloud-images.ubuntu.com/releases/18.04/release/${img}"
qemu-img resize "$img" +60G
fi
# 암호 설정.
user_data=user-data.img
if [ ! -f "$user_data" ]; then
cat >user-data <<EOF
#cloud-config
password: totoro
chpasswd: { expire: False }
ssh_pwauth: True
EOF
cloud-localds "$user_data" user-data
# EFI 사용:
# https://wiki.ubuntu.com/ARM64/QEMU
dd if=/dev/zero of=flash0.img bs=1M count=64
dd if=/usr/share/qemu-efi/QEMU_EFI.fd of=flash0.img conv=notrunc
dd if=/dev/zero of=flash1.img bs=1M count=64
fi
qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-device rtl8139,netdev=net0 \
-m 4096 \
-netdev user,id=net0 \
-nographic \
-smp 4 \
-drive "if=none,file=${img},id=hd0" \
-device virtio-blk-device,drive=hd0 \
-drive "file=${user_data},format=raw" \
-pflash flash0.img \
-pflash flash1.img \
;
sudo apt-get install qemu-efi
자동 스크립트
vi uefi_cloud_image.sh
#!/usr/bin/env bash
set -eux
#sudo apt-get install cloud-image-utils qemu-system-arm qemu-efi
# 이미지 다운로드.
img=ubuntu-18.04-server-cloudimg-arm64.img
if [ ! -f "$img" ]; then
wget "https://cloud-images.ubuntu.com/releases/18.04/release/${img}"
qemu-img resize "$img" +60G
fi
# 암호 설정.
user_data=user-data.img
if [ ! -f "$user_data" ]; then
cat >user-data <<EOF
#cloud-config
password: totoro
chpasswd: { expire: False }
ssh_pwauth: True
EOF
cloud-localds "$user_data" user-data
# EFI 사용:
# https://wiki.ubuntu.com/ARM64/QEMU
dd if=/dev/zero of=flash0.img bs=1M count=64
dd if=/usr/share/qemu-efi/QEMU_EFI.fd of=flash0.img conv=notrunc
dd if=/dev/zero of=flash1.img bs=1M count=64
fi
qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-device rtl8139,netdev=net0 \
-m 4096 \
-netdev user,id=net0 \
-nographic \
-smp 4 \
-drive "if=none,file=${img},id=hd0" \
-device virtio-blk-device,drive=hd0 \
-drive "file=${user_data},format=raw" \
-pflash flash0.img \
-pflash flash1.img \
;
login: ubuntu
pw:totoro
ubuntu wayland manager qemu kvm 활성화
Unable to init server: Could not connect: Connection refused
사용자 추가(sudo GUI + terminal)
xhost -si:localuser:root
GL에서 GPU 장치 선택
GL에서 GPU 장치 선택
OpenGL 자체가 렌더링 API임.
GLX, WGL, EGL과 같은 윈도우 시스템 바인딩 API는 수 많은 세월에 거쳐 만들어짐.
멀티 GPU 시스템이 찾기 어려웠던 시대...
멀티 GPU API는 제조사 마다 다르지만 MESA 솔루션의 DRI_PRIME를 통해 발전함.
DRI_PRIME란?
초창기의 DRI_PRIME는 2개의 GPU에서 동작 하도록 정의한 환경 변수.
응용 프로그램 호출하기 전에 1로 설정하면 GL 스택이 X서버로 쿼리하고 시스템에 있는 다른 GPU를 사용.
이러한 방법으르로 초기에 발전 함.
- 시스템에 GPU가 3개 이상 있을때?
- x 서버가 없는 시스템일 때?
- 응용 프로그램 개발시 사용할 GPU를 어떻게 선택해 사용할 것인가?
사용자 ID_PATH_TAG가 udev에서 제공 한대로 DRI_PRIME 장치를 나열하여 선택할 수 있다.
EGL의 확장 가능구조 덕분에 EGLDevice 계열의 확장을 통해 해결할 수 있음.
EGLDevice 입력
EGL_EXT_device_base 확장 측면에서 구현된 EGL_EXT_device_enumeration 및 EGL_EXT_device_query.
EGLDevice는 장치고유 속성을 나열해 질문하는 수단 인 EGLDevice의 개념 정의.
또 다른 두 개의 확장 EGL_EXT_device_drm 및 EGL_MESA_device_software은
각각의 하드웨어 DRM 장치 노드 및 소프트웨어와 백업 장치 정의
- 메사로 사용해 GL 구현.
사용 사례
확장 세트를 사용하려면 어떤 장치를 사용할지 명시 적으로 선택한다
그래픽 서버/윈도우 메이지먼트는 전력 소모가 적은 장치로 렌더링한다.
webGL 신뢰할 수 없는 장치로 분류 할 수 있고, 시간 기준으로 GPU 작업을 처리한다.
구현 상태
EGL_EXT_device_base- 구현 모두 EGL_EXT_device_enumeration와EGL_EXT_device_query
EGL_EXT_device_drm
EGL_MESA_device_software
EGL_EXT_platform_device
OpenGL 자체가 렌더링 API임.
GLX, WGL, EGL과 같은 윈도우 시스템 바인딩 API는 수 많은 세월에 거쳐 만들어짐.
멀티 GPU 시스템이 찾기 어려웠던 시대...
멀티 GPU API는 제조사 마다 다르지만 MESA 솔루션의 DRI_PRIME를 통해 발전함.
DRI_PRIME란?
초창기의 DRI_PRIME는 2개의 GPU에서 동작 하도록 정의한 환경 변수.
응용 프로그램 호출하기 전에 1로 설정하면 GL 스택이 X서버로 쿼리하고 시스템에 있는 다른 GPU를 사용.
이러한 방법으르로 초기에 발전 함.
- 시스템에 GPU가 3개 이상 있을때?
- x 서버가 없는 시스템일 때?
- 응용 프로그램 개발시 사용할 GPU를 어떻게 선택해 사용할 것인가?
사용자 ID_PATH_TAG가 udev에서 제공 한대로 DRI_PRIME 장치를 나열하여 선택할 수 있다.
EGL의 확장 가능구조 덕분에 EGLDevice 계열의 확장을 통해 해결할 수 있음.
EGLDevice 입력
EGL_EXT_device_base 확장 측면에서 구현된 EGL_EXT_device_enumeration 및 EGL_EXT_device_query.
EGLDevice는 장치고유 속성을 나열해 질문하는 수단 인 EGLDevice의 개념 정의.
또 다른 두 개의 확장 EGL_EXT_device_drm 및 EGL_MESA_device_software은
각각의 하드웨어 DRM 장치 노드 및 소프트웨어와 백업 장치 정의
- 메사로 사용해 GL 구현.
사용 사례
확장 세트를 사용하려면 어떤 장치를 사용할지 명시 적으로 선택한다
그래픽 서버/윈도우 메이지먼트는 전력 소모가 적은 장치로 렌더링한다.
webGL 신뢰할 수 없는 장치로 분류 할 수 있고, 시간 기준으로 GPU 작업을 처리한다.
구현 상태
EGL_EXT_device_base- 구현 모두 EGL_EXT_device_enumeration와EGL_EXT_device_query
EGL_EXT_device_drm
EGL_MESA_device_software
EGL_EXT_platform_device
Cloud image amd64
1. Cloud image amd64
데스크탑 시스템 설치없이 직접 부팅 할 수있는 이미지임.
이게 가능한 이유는 https://help.ubuntu.com/community/CloudInit
여기 사이트에 설명 되어 있음.
즉 init 개념을 -> Cloudint 개념을 추가해 부팅 시퀀서를 만듬.
이미지 생성 스크립트
vi upstream.sh
#!/usr/bin/env bash
sudo apt-get install cloud-image-utils qemu qemu-system qemu-system-x86
# qcow2 형식.
img=ubuntu-18.04-server-cloudimg-amd64.img
if [ ! -f "$img" ]; then
wget "https://cloud-images.ubuntu.com/releases/18.04/release/${img}"
# sparse resize: 추가 공간을 사용하지 않고 나중 크기 변경 허용.
# https://superuser.com/questions/1022019/how-to-increase-size-of-an-ubuntu-cloud-image
qemu-img resize "$img" +128G
fi
user_data=user-data.img
if [ ! -f "$user_data" ]; then
# 암호.
# https://serverfault.com/questions/920117/how-do-i-set-a-password-on-an-ubuntu-cloud-image
# https://askubuntu.com/questions/507345/how-to-set-a-password-for-ubuntu-cloud-images-ie-not-use-ssh
cat >user-data <<EOF
#cloud-config
password: totoro
chpasswd: { expire: False }
ssh_pwauth: True
EOF
cloud-localds "$user_data" user-data
fi
qemu-system-x86_64 \
-drive "file=${img},format=qcow2" \
-drive "file=${user_data},format=raw" \
-device rtl8139,netdev=net0 \
-enable-kvm \
-m 2G \
-netdev user,id=net0 \
-serial mon:stdio \
-smp 2 \
-vga virtio \
;
:wq
QEMU 시작 후 부트 메뉴가 나타나면, 엔터 입력.
부트 메시지
error: no such device: root.
Press any key to continue...
특정 시간이 지나면 자동 부팅 됨.
사용자 이름: ubuntu
암호: totoro
인터넷 동작 확인.
데스크탑 시스템 설치없이 직접 부팅 할 수있는 이미지임.
이게 가능한 이유는 https://help.ubuntu.com/community/CloudInit
여기 사이트에 설명 되어 있음.
즉 init 개념을 -> Cloudint 개념을 추가해 부팅 시퀀서를 만듬.
이미지 생성 스크립트
vi upstream.sh
#!/usr/bin/env bash
sudo apt-get install cloud-image-utils qemu qemu-system qemu-system-x86
# qcow2 형식.
img=ubuntu-18.04-server-cloudimg-amd64.img
if [ ! -f "$img" ]; then
wget "https://cloud-images.ubuntu.com/releases/18.04/release/${img}"
# sparse resize: 추가 공간을 사용하지 않고 나중 크기 변경 허용.
# https://superuser.com/questions/1022019/how-to-increase-size-of-an-ubuntu-cloud-image
qemu-img resize "$img" +128G
fi
user_data=user-data.img
if [ ! -f "$user_data" ]; then
# 암호.
# https://serverfault.com/questions/920117/how-do-i-set-a-password-on-an-ubuntu-cloud-image
# https://askubuntu.com/questions/507345/how-to-set-a-password-for-ubuntu-cloud-images-ie-not-use-ssh
cat >user-data <<EOF
#cloud-config
password: totoro
chpasswd: { expire: False }
ssh_pwauth: True
EOF
cloud-localds "$user_data" user-data
fi
qemu-system-x86_64 \
-drive "file=${img},format=qcow2" \
-drive "file=${user_data},format=raw" \
-device rtl8139,netdev=net0 \
-enable-kvm \
-m 2G \
-netdev user,id=net0 \
-serial mon:stdio \
-smp 2 \
-vga virtio \
;
:wq
QEMU 시작 후 부트 메뉴가 나타나면, 엔터 입력.
부트 메시지
error: no such device: root.
Press any key to continue...
특정 시간이 지나면 자동 부팅 됨.
사용자 이름: ubuntu
암호: totoro
인터넷 동작 확인.
callback test
/*
* Callback.c - 연결 목록 콜백 구현
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct NODE {
struct NODE *link;
int data;
}Node;
Node **create_sll(const int);
void insert_data(Node **);
void show_list(Node **);
void sort_list(Node **);
int compare_ints(void const *, void const *); /* 프로토타입 함수 */
Node *search_list(Node *, void const *, int(void const *, void const *)); /* 프로토타입 */
int main(void){
int (*compare)(void const *, void const *) = compare_ints;
int value, val2find;
int nodes; /* 노트 카운트 */
Node **rootp; /* 루투 위치 */
Node *desired_node;
puts("\n**Program creates Singly Linked List**");
puts("**And allows users to perform various operations on the"
"list**\n");
puts("User, specify number of nodes in the list, in range 1"
" through some positive no.");
scanf("%d", &nodes);
rootp = create_sll(nodes);
printf("Les's insert %d integers in the list...\n", nodes);
insert_data(rootp);
puts("**Les's show up the list**");
show_list(rootp);
puts("Let's sort the list, in ascending order...");
sort_list(rootp);
puts("Let's show up the list**");
show_list(rootp);
puts("**Let's use Callback() function**");
printf("User, enter an integer you want to see into the "
"Singly Linked List...\n");
scanf("%d", &val2find);
/* 콜밸 함수 호출 */
desired_node = search_list(*rootp, &val2find, compare);
if(desired_node != NULL)
puts("Desired value is found.");
else
puts("Desired value NOT found.");
return 0;
}
Node *search_list(Node *node, void const *value, int compare(void const *, void const *)){
while(node != NULL){
if(compare(&node->data, value) == 0)
break;
node = node->link;
}
return node;
}
int compare_ints(void const *p2nv, void const *p2v){
if(*(int *)p2nv == *(int *)p2v)
return 0;
else
return 1;
}
Node **create_sll(const int nodes){
int i;
Node *current;
static Node *root;
Node **rootp = &root;
root = (Node *)malloc(nodes * sizeof(Node));
if(root == NULL){
puts("Error: Not Enough Memory!");
exit(1);
} else {
current = root;
for(i = 1; i <= nodes; i++){
if(i == nodes) {
current->link = NULL;
} else {
current->link = current + 1;
current++;
}
}
printf("List with %d nodes created successfully!\n", nodes);
puts("");
}
return rootp;
}
void insert_data(Node **linkp){
Node *next = *linkp;
Node *current;
do {
current = next;
scanf("%d", &(current->data));
next = current->link;
}while(current->link != NULL);
puts("");
}
void show_list(Node **linkp){
Node *next = *linkp;
Node *current;
do{
current = next;
printf("%d", current->data);
next = current->link;
}while(current->link != NULL);
puts("\n");
}
void sort_list(Node **linkp){
int temp;
Node *current = *linkp;
Node *next = current->link;
while(current->link != NULL){
while(next != NULL){
if(current->data > next->data){
temp = next->data;
next->data = current->data;
current->data = temp;
}
next = next->link;
}
current = current->link;
next = current->link;
}
}
/*
* ./callback
**Program creates Singly Linked List**
**And allows users to perform various operations on thelist**
User, specify number of nodes in the list, in range 1 through some positive no.
5
List with 5 nodes created successfully!
Les's insert 5 integers in the list...
32
53
1
08
0556
**Les's show up the list**
325318556
Let's sort the list, in ascending order...
Let's show up the list**
183253556
**Let's use Callback() function**
User, enter an integer you want to see into the Singly Linked List...
53
Desired value is found */
* Callback.c - 연결 목록 콜백 구현
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct NODE {
struct NODE *link;
int data;
}Node;
Node **create_sll(const int);
void insert_data(Node **);
void show_list(Node **);
void sort_list(Node **);
int compare_ints(void const *, void const *); /* 프로토타입 함수 */
Node *search_list(Node *, void const *, int(void const *, void const *)); /* 프로토타입 */
int main(void){
int (*compare)(void const *, void const *) = compare_ints;
int value, val2find;
int nodes; /* 노트 카운트 */
Node **rootp; /* 루투 위치 */
Node *desired_node;
puts("\n**Program creates Singly Linked List**");
puts("**And allows users to perform various operations on the"
"list**\n");
puts("User, specify number of nodes in the list, in range 1"
" through some positive no.");
scanf("%d", &nodes);
rootp = create_sll(nodes);
printf("Les's insert %d integers in the list...\n", nodes);
insert_data(rootp);
puts("**Les's show up the list**");
show_list(rootp);
puts("Let's sort the list, in ascending order...");
sort_list(rootp);
puts("Let's show up the list**");
show_list(rootp);
puts("**Let's use Callback() function**");
printf("User, enter an integer you want to see into the "
"Singly Linked List...\n");
scanf("%d", &val2find);
/* 콜밸 함수 호출 */
desired_node = search_list(*rootp, &val2find, compare);
if(desired_node != NULL)
puts("Desired value is found.");
else
puts("Desired value NOT found.");
return 0;
}
Node *search_list(Node *node, void const *value, int compare(void const *, void const *)){
while(node != NULL){
if(compare(&node->data, value) == 0)
break;
node = node->link;
}
return node;
}
int compare_ints(void const *p2nv, void const *p2v){
if(*(int *)p2nv == *(int *)p2v)
return 0;
else
return 1;
}
Node **create_sll(const int nodes){
int i;
Node *current;
static Node *root;
Node **rootp = &root;
root = (Node *)malloc(nodes * sizeof(Node));
if(root == NULL){
puts("Error: Not Enough Memory!");
exit(1);
} else {
current = root;
for(i = 1; i <= nodes; i++){
if(i == nodes) {
current->link = NULL;
} else {
current->link = current + 1;
current++;
}
}
printf("List with %d nodes created successfully!\n", nodes);
puts("");
}
return rootp;
}
void insert_data(Node **linkp){
Node *next = *linkp;
Node *current;
do {
current = next;
scanf("%d", &(current->data));
next = current->link;
}while(current->link != NULL);
puts("");
}
void show_list(Node **linkp){
Node *next = *linkp;
Node *current;
do{
current = next;
printf("%d", current->data);
next = current->link;
}while(current->link != NULL);
puts("\n");
}
void sort_list(Node **linkp){
int temp;
Node *current = *linkp;
Node *next = current->link;
while(current->link != NULL){
while(next != NULL){
if(current->data > next->data){
temp = next->data;
next->data = current->data;
current->data = temp;
}
next = next->link;
}
current = current->link;
next = current->link;
}
}
/*
* ./callback
**Program creates Singly Linked List**
**And allows users to perform various operations on thelist**
User, specify number of nodes in the list, in range 1 through some positive no.
5
List with 5 nodes created successfully!
Les's insert 5 integers in the list...
32
53
1
08
0556
**Les's show up the list**
325318556
Let's sort the list, in ascending order...
Let's show up the list**
183253556
**Let's use Callback() function**
User, enter an integer you want to see into the Singly Linked List...
53
Desired value is found */
피드 구독하기:
글 (Atom)