일반적인 Linux 배포판을 쓰지 않고, Kernel source와 Root file system 으로 부터 Linux system 을 구성한 경우,

Linux runtime 에 kernel module을 compile 하여 insmod/rmmod 를 할 수 있다.


Kernel module을 컴파일 하기 위해서는 현재 Linux system 에서 사용되고 있는 kernel source를 필요로 한다.

일반적인 방법과 유사하게 사용하기 위해

kernel source 를 /usr/src 디렉토리에 위치시키고,

/lib/modules/<kernel_version>/build 와 symbolic link 시킨다.

# cd /lib/modules/<kernel_version>

# ln -s /usr/src/<kernel_source_dir> build

커널 모듈을 컴파일 하기 위한 준비 작업은 아래 와 같다.

# cd /usr/src/<kernel_source_dir>

# make <defconfig>

# make prepare

# make scripts

※ 참조: http://www.fun25.co.kr/blog/linux-ubuntu-14-04-kernel-module-compile


kernel module을 컴파일 할 Makefile은 아래와 같이 구성한다.

obj-m := test_module.o


all:

make -C /lib/modules/<kernel_version>/build M=$(PWD) modules

clean:

make -C /lib/modules/<kernel_version>/build M=$(PWD) clean

아래는 테스트를 위한 기본적인 kernel module source code.

#include <linux/module.h>

#include <linux/kernel.h>


int init_module(void){

printk(KERN_ALERT"Hello"\n);

return 0;

}


void cleanup_module(void){

printk(KERN_ALERT"Bye"\n);

}


kernel module을 컴파일 하고, insmod/rmmod 를 통해 test 한다.

# make

# insmod <kernel_module>.ko

# rmmod <kernel_module>.ko

※ 이 때, 현재 Linux system 에서 사용되는 kernel 과 다른 source로 부터 kernel module을 컴파일 하게 되면 version 차이로 오류가 나타난다.

'Programming > Linux Kernel' 카테고리의 다른 글

cross kernel debugging  (0) 2020.06.19
Kernel module programming  (0) 2018.05.23
Kernel Version Check  (0) 2018.05.23
Kernel 프로그래밍 - printk  (0) 2017.06.20

Ubuntu 에서 Headless browser 인 PhantomJS를 설치하는 방법을 소개한다.


PhantomJS는 기본적으로 Multi platform 을 지원하여, Windows, Linux, FreeBSD 등 다양한 OS 상에서 구동 될 수 있다.

Architecture / OS 에 따라 기본적으로 제공되는 파일을 사용하여 설치 할 수 없는 경우

Github 로 부터 source code를 다운 받아 설치 할 수 있다.


PhantomJS에서 필요한 패키지(Qt, WebKit 등)를 자동으로 설치 하기 떄문에 Dependency가 없다고 하지만,

Ruby, gperf 등 일부 패키지를 설치 하지 않으면 install 도중 Error를 맞이하게 된다.


Prerequisites

1. Ruby Installation

Ruby install은 RVM(Ruby Version Manager)를 통해 할 수 있다. 따라서, Ruby install 을 위한 RVM install 이 필요하다. 

gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

$ cd /tmp && \curl -sSL https://get.rvm.io -o rvm.sh

$ cat /tmp/rvm.sh | bash -s stable

*참조: https://www.rosehosting.com/blog/install-ruby-on-rails-on-ubuntu-16-04/

RVM이 설치 되면, Ruby를 설치 할 수 있다. 


RVM 실행

$ source /usr/local/rvm/scripts/rvm


RVM에서 설치 가능한 Ruby version 확인

$ rvm list known


Ruby 설치(stable 최신 버전 2.5.1, 2018.12.10 기준)

$ rvm install 2.5.1


2. Gperf Installation

$ sudo apt-get install gperf


Git source Fetch

$ git clone https://github.com/ariya/phantomjs


PhantomJS Installation from source

$ cd phantomjs

$ ./build.py 

(시간이 꽤 걸린다.)

'Programming > Linux' 카테고리의 다른 글

Piping ls to cp  (0) 2020.12.02
How to use GDB  (0) 2020.03.12
Linux screen  (0) 2018.09.27
Xshell + Xming  (0) 2018.09.10
Memtester  (0) 2018.07.15

라즈비안이 들어있는 SD 카드를 이미지로 백업하고 싶은 경우 

Win 32 Disk Imager 로 백업 이미지를 만들 수 있다.


방법은 간단하다.

1. Win 32 Disk Imager 설치

2. Backup 할 SD 카드를 꼽고

3. Win 32 Disk Imager 에서 Backup 할 Drive를 선택 + output Image 가 될 파일을 지정

※ 파티션이 여러개 여서, 여러 개의 Drive로 보이더라도, Linux File system 이라 윈도우에서 안보이는 경우여도 첫 번째 파티션을 선택하면 전체 백업 된다.

4. Read


백업된 이미지를 다시 SD 카드에 쓰기위해서는

1. Win 32 Disk Imager 에서 Backup 된 image를 선택 + Drive 지정

2. Write

※ 이때, Backup 된 이미지는 기존 SD 카드의 크기를 가지기 때문에, 복원을 위해서는 기존 SD 카드의 크기보다 크거나 같은 SD 카드가 필요하며, 기존 SD 카드보다 큰 SD 카드의 경우 복원 후 resize 가 필요하다.


'Programming > RaspberryPi' 카테고리의 다른 글

Install Owncloud on RaspberryPi  (0) 2023.03.15
Rasbian qbittorrent-nox installation  (0) 2019.11.19
SDcard Partition Resize  (0) 2018.08.21
RaspberryPi Remote Desktop Client  (0) 2018.06.01
Raspbian Korean(Hangul) Install  (0) 2018.05.18

Linux 명령어 중에 Shell 접속이 끊어지더라도, 프로세스를 죽이지 않기 위해 screen 을 사용할 수 있다.


screen 은 가상의 shell을 담당하여, 실제 shell의 접속 여부와 상관없이 프로세스를 계속적으로 진행하게 해준다.


초간단 사용법

1. 스크린 생성

$ screen

screen 명령어에 아무런 옵션이 없는 경우 임의의 이름을 가지는 screen을 생성한다.

이름을 지정하기 위해서는 screen -S <NAME> 과 같이 -S 옵션을 사용하면 된다.


2. Detach

screen에 접속한 상태에서 screen으로 명령을 전달하기 위해서는 ctrl+a 를 입력 한 뒤에 명령을 입력해야 한다.

screen에서 접속을 해제하는 detach 명령어는 d 이다


3. List 확인

Detach 한 screen에 재접속(Reattach) 하기 위해서는 우선 해당 screen의 이름을 알거나, Process ID를 알아야 한다.

Screen의 Process ID를 확인하기 위해서는 아래와 같이 -x 옵션을 사용한다.

$ screen -x

이 때, 활성화된 screen 이 1개밖에 없는 경우, 해당 screen으로 바로 재접속(Reattach) 된다.


4. Reattach

3에서 확인한 Process ID 혹은 screen 이름으로 Reattach 하는 명령은 -r 옵션을 사용한다.

$ screen -r <Process_ID | screen_name>


5. Kill

screen에 접속한 상태에서 해당 screen을 kill 하는 명령어는 k 이다.

Kill 명령의 경우 진짜로 죽일 것인지 한 번 더 확인한다.


6. Screen for running multiple processes

Screen command option 중 -dmS 옵션을 사용하면 각 Process를 동작하는 screen을 여러개 생성할 수 있다. 프로세스가 종료되면 screen 또한 종료된다.

Bash script 와 함께 활용하면 유용하다.

#!/bin/bash


for size in 2 4 8 16 32

do

    screen -dmS screen_${size} ./test.sh ${size}

done


'Programming > Linux' 카테고리의 다른 글

How to use GDB  (0) 2020.03.12
PhantomJS Installation on Ubuntu from source  (0) 2018.12.10
Xshell + Xming  (0) 2018.09.10
Memtester  (0) 2018.07.15
Ctags  (0) 2018.07.03

Netsarang의 Xshell, Xftp 는 개인/학교 사용자의 경우 무료로 사용할 수 있다.

무료 버전과 유료 버전의 차이 점은 동시에 열 수 있는 shell 의 갯수의 제한 정도라고 하는데,

Xshell 과 Xftp만 무료이기 때문에, 유료로 구매하지 않으면 Xmanager(X11 포워딩) 을 사용할 수 없다.


따라서, Xming을 사용하여 X11 포워딩을 설정하여 사용한다.

(Xming 또한 무료)


Xming은 SourceForge.net에서 다운 받을 수 있다.


Xshell 실행 후 

파일 - 열기 - 세션 등록정보 에서

SSH - 터널링 의 X11 포워딩을 아래와 같이 설정해 주면 된다.

* 출처: https://www.netsarang.com/tutorial/xshell/2779/Using_X11_forwarding


혹은 Xshell 기본 세션 정보에서 수정하면, 기본 설정으로 X11 Forwarding 을 localhost:0.0으로 수정할 수 있다.

기본 세션 정보는 일반적으로 C:\Users\<User_name>\Documents\Netsarang Computer\Xshell\6\Xshell\Sessions\default 에 위치한다.

파일을 열어 

ForwardToXmanager=1 을

ForwardToXmanager=0 으로 수정한다.


Xming 으로 X11 포워딩 시 Xming이 사전에 실행되어 있어야 한다.

윈도우 시작프로그램으로 등록하는 것도 한 방법!


'Programming > Linux' 카테고리의 다른 글

PhantomJS Installation on Ubuntu from source  (0) 2018.12.10
Linux screen  (0) 2018.09.27
Memtester  (0) 2018.07.15
Ctags  (0) 2018.07.03
scp  (0) 2018.05.29

라즈베리파이 등을 사용할 때, Root Filesystem의 size가 실제 SD 카드의 사이즈 보다 작게 인식 되는 경우가 있다.

라즈베리 파이의 경우에는 raspi-config를 사용하여 resize 할 수 있지만,

일반적인 Command를 사용해서 resize 하는 방법은 아래와 같다.

해당 과정 중에 문제가 생기는 경우 Kernel panic으로 다시 살릴 수 없기에 SD카드를 백업해 둘 것을 추천한다.

 - 백업은 win32 DiskImager로 Read 하면 이미지로 백업 가능. 추후 write로 복원


1. 현재 partition 확인

fdisk 로 device 정보 확인 후,

$ fdisk -l


해당 디바이스의 사이즈가 실제 디바이스의 사이즈보다 작은 경우

partition table을 다시 작성해준다.

이 때, partition table Start sector를 확인해 둔다.

$ fdisk /dev/mmcblk0


우선 기존의 작게 인식되는 partition을 삭제해 준다.

Command (m for help): d

Partition number (1,2, default 2): 2


새로 partition을 추가 한다.

이때, start sector가 위에서 확인한 기존 partition table과 일치해야 kernel panic이 나지 않을 것이다.

Command (m for help): n

Partition type

p    primary (1 primary, 0 extended, 3 free)

e     extended (container for logical partitions)

Select (default p): p

Partition number (2-4, default 2): 2

First sector (2088450-31116287, default 2088960): 2088450

Last sector, +sectors or +size{K,M,G,T,P} (2088450-31116287, default 31116287): 


작성된 partition table을 저장 하고 종료한다.

Command (m for help): w


현재 사용 중인 시스템에서는 partition table을 다시 작성한 것이 재부팅 후에 인식이 되므로, 시스템을 재부팅 해준다.

$ shutdown -r now


재부팅 된 시스템에서, partition 사이즈가 제대로 인식이 되는지 확인한다.

$ fdisk -l


제대로 인식이 됐다면, resize를 해준다.

$ resize2fs /dev/mmcblk0p2


끗.

'Programming > RaspberryPi' 카테고리의 다른 글

Rasbian qbittorrent-nox installation  (0) 2019.11.19
SD card image backup  (0) 2018.10.12
RaspberryPi Remote Desktop Client  (0) 2018.06.01
Raspbian Korean(Hangul) Install  (0) 2018.05.18
Raspbian Install  (0) 2018.05.16

wget 등 사용 시 Progress가 프린팅 된다.

Carriage return(\r) 과 fflush를 활용하면 이쁘게 Progress를 print 할 수 있다.


percent = (float)i*100/(MEM_SIZE/sizeof(int));

printf("\r[");

for(j=0; j<50; j++){

if(j<(int)percent/2)

        printf(">");

else

printf(" ");

}

printf("]%.2f%%",percent);

fflush(stdout);


'Programming > C Language' 카테고리의 다른 글

Check the system's Endianness  (0) 2019.04.23
static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20

인터넷이 되지 않는 어떤 머신에

OS가 Ubuntu가 설치 된 경우

apt get을 통해 패키지를 설치하고 싶지만, 인터넷이 되지 않기에 

인터넷이 되는 다른 머신에서 repository에서 필요한 패키지를 찾아 직접 설치 해야 한다.


Python을 이용해 이를 자동화 할 수 있는 코드를 짜보았다.

import gzip

import os

import wget

import sys


repository="old-releases.ubuntu.com/ubuntu"

ARCH="arm64"

release="vivid"

branch="main"


def check_dependency(package_depends):

if package_depends == None:

return;

depends_list_pre = package_depends.split(", ")

depends_list_post = [] #[depend_package, version, comparator]

for depend in depends_list_pre:

if depend.find("(") != -1:

depend_package = depend[:depend.find("(")-1]

version = depend[depend.find(" ", depend.find("("))+1:depend.find(")")]

comparator = depend[depend.find("(")+1: depend.find(" ", depend.find("("))]

else:

depend_package = depend

version = ""

comparator = ""

depends_list_post.append([depend_package, version, comparator])

print(depends_list_post)

for depend, ver, com in depends_list_post:

find_package(depend, ver, com)


def down_pacakge(filename):

file_path_and_name = filename.split("/")

if not os.path.exists("./"+repository+"/"+release+"/"+branch+"/deb/"+file_path_and_name[-1]):

url = "http://"+repository+"/"+filename

print(url)

wget.download(url, "./"+repository+"/"+release+"/"+branch+"/deb/"+file_path_and_name[-1])

return 1;

return 0;

def find_package(package_name, version="", comparator=""):

package_list_file = "./"+repository+"/"+release+"/"+branch+"/binary-"+ARCH+"/Packages.gz"

if not os.path.exists(package_list_file):

if not os.path.exists("./"+repository+"/"+release+"/"+branch+"/binary-"+ARCH):

os.mkdir("./"+repository+"/"+release+"/"+branch+"/binary-"+ARCH)

#download Packages.gz

url = "http://"+repository+"/dists/"+release+"/"+branch+"/binary-"+ARCH+"/Packages.gz"

wget.download(url, package_list_file)

package_list = []

package_info = {}

package_list_filep = gzip.open(package_list_file, 'r')

for line in package_list_filep:

line_str = line.decode("utf-8")

line_str = line_str.replace("\n", "")

if line_str == "":

package_list.append(package_info)

package_info = {}

else:

line_elements = line_str.split(": ")

package_info.update({line_elements[0] : line_elements[1]})

package_list_filep.close()

for package in package_list:

if package.get("Package") == package_name:

if(version==""):

if down_pacakge(package.get("Filename")):

check_dependency(package.get("Depends"))

return package;

elif comparator == "=" and package.get("Version") == version:

if down_pacakge(package.get("Filename")):

check_dependency(package.get("Depends"))

return package;

elif comparator == ">=" and package.get("Version") >= version:

if down_pacakge(package.get("Filename")):

check_dependency(package.get("Depends"))

return package;

print("ERROR::Cannot find package("+package_name+")")


for argument in sys.argv:

if argument == "apt_get.py":

continue;

else:

find_package(argument)


패키지는 해당 머신에 복사해주시고,

설치는 아래와 같이 하면 된다.

$ sudo dpkg -i *.deb


원리는 간단하다.

repository 에는 package 정보가 담긴 파일이 존재하고(architecture / release / branch)

해당 파일에는 Package 의 이름, 버전, dependency, 패키지 파일 경로 등이 담겨 있다.

패키지 설치를 위해서는 각 패키지 파일(.deb)을 다운 받아야하고, 또한 dependency 파일들의 패키지 파일도 다운 받아야 한다.

다운받은 모든 파일을 dpkg 를 통해 한 번에 설치 하면 된다.




Ubuntu 패키지 중에 Memory(RAM) 를 테스트하기 위한 패키지가 있다

Memtester 


성능 분석을 할 수는 없고, Bit flip 등 error 가 발생하는 지 여부를 확인 할 수 있다.


설치

$ sudo apt-get install memtester


사용 방법

memtester <size_in_MB> <#_of_loops>

-p 와 함께 physical address base를 지정할 수 있다.


참조: https://www.techwalla.com/articles/how-to-reinstall-usb-mouse-drivers-in-ubuntu-using-the-command-line

'Programming > Linux' 카테고리의 다른 글

Linux screen  (0) 2018.09.27
Xshell + Xming  (0) 2018.09.10
Ctags  (0) 2018.07.03
scp  (0) 2018.05.29
Systemd Service  (0) 2018.05.04

일반적으로 C언어에서, 지역 변수는 함수 내에서 존재하고, 함수가 종료되는 시점에 사라지게 된다.

이때 사라지지 않고 기존의 값을 보존하게 하기 위한 keyword 가 static 이다.


static keyword를 사용하면, 지역 변수가 함수 종료 때 사라지지 않고, 값을 보존하게 된다.


주의!!! static은 전역 변수에서 사용하여, 다른 파일에서 extern 해서 사용할 수 없다.

'Programming > C Language' 카테고리의 다른 글

Check the system's Endianness  (0) 2019.04.23
C progress printing  (0) 2018.08.07
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20

+ Recent posts