2010년 9월 10일 금요일
There is no /dev/dsp !!!!
2010년 7월 29일 목요일
svn+ssh:// 자동 로그인
$ ls
$ ssh-add
2010년 6월 24일 목요일
SubVersion 설정
$ mkdir svn
$ cd svn
$ svnadmin create test
$ svnadmin create --fs-type bdb test (버클리DB)
... 중략 ...
anon-access = none //아무나 접근할 수 없게 함
auth-access = write //인증된 사용자에게만 쓰기 권한을 줌
...
password-db = passwd
....
realm = My First Repository
$ cd .subversion
$ vi config
ssh = ssh -l test
2010년 6월 21일 월요일
clamAV(Anti Virus) 설치
$ yum install clamav
$ clamscan -r
2010년 6월 1일 화요일
네트워크 설정
nameserver 168.126.63.2
BOOTPROTO=static
ONBOOT=yes
TYPE=Ethernet
NETMASK=255.255.255.0
IPADDR=192.168.10.101
GATEWAY=192.168.10.1
USERCTL=no
PEERDNS=yes
IPV6INIT=no
2010년 5월 31일 월요일
X window 설치 명령어
2009년 10월 20일 화요일
ip 주소 설정/변경하기
2008년 11월 24일 월요일
시스템 콜 추가
asmlinkage 반환형 sys_함수이름 ( arg1, arg2.......)
{
2. system call 번호 추가
include/asm/unistd.h 파일을 수정한다.
맨 아래쪽에 __NR_함수이름을 쓰고 번호를 지정해준다.
3. system call table에 추가
arch/i386/kernel/entry.S 파일을 수정한다.
ENTRY(sys_call_table) 이라고 되어있는 곳 맨 끝에 새롭게 정의한 시스템콜 함수 이름을 적는다.
.long sys_함수이름
4. 커널컴파일
$ make
2008년 10월 15일 수요일
autogen 사용
1. Makefile.am과 Makefile.in을 복사해온다. (귀찮으니까)
2. 컴파일 할 소스와 같은 디렉토리 내에 있는 Makefile.am을 열어서 실행파일 이름을 바꾼다.
noinst_PROGRAMS 라고 되어 있는 부분에 이름을 바꾸면 된다.
이 이름을 바꾼후에 OURCES와 LDADD도 실행 파일이름으로 바꾸어 주어야 한다.
만약, 실행파일 이름이 test라면,
noinst_PROGRAMS = test
test_SOURCES = 소스파일
test_LDADD
... 이런식으로 수정한다.
3. 만약 상위디렉토리가 있다면 그곳에 있는 Makefile.am도 수정한다.
SUBDIRS에다가 새로 만든 디렉토리 이름을 추가한다.
4. autogen이 있는 곳에 configure.ac 라는 파일을 수정한다.
AC_CONFIG_FILES 에 현재 디렉토리로부터 새로 만들 Makefile의 경로를 써준다.
5. autogen실행
$ ./autogen.sh
아무런 메세지가 뜨지 않은 다면 성공.
6. 적절한 옵션과 함께 configure하고 나면 4단계에서 지정해준 경로에 Makefile이 생성되어 있을 것이다.
7. 컴파일 한다.
$ make
그럼 실행파일이 생성된다.
2008년 8월 4일 월요일
리눅스에서 윈도우 원격접속
rdesktop으로 원격접속을 해보자.
1. install
rdesktop 다운로드
다운로드를 받고 압축을 푼다.
압축을 푼 디렉토리로 이동하여 다음 명령어를 수행한다.
$ ./configure (몇몇 패키지가 설치되어 있지 않다고 투덜대면 패키지를 설치하고 다시 한다.)
$ make
$ make install
2. 사용하기
위와 같은 방법으로 rdesktop을 설치하였다면 이제 사용하면 된다
$ rdesktop -a 16 -f ipaddr
-a는 해상도 옵션(16bit을 의미)
-f는 fullscreen이다.
윈도우 화면이 뜰 것이다+_+!
와우.
2008년 8월 1일 금요일
nfs 설치
우선, nfs 패키지를 인스톨 해야한다.
$ yum install nfs-util (맞나? 암튼 비슷한 이름의 패키지이다;;)
2. 설정
/etc에 가보면 exports라는 파일이 있다.
그 파일을 열어보면 아무것도 없을 수도 있고, default로 뭔가 저장되어 있을 수도 있다.
이 파일을 수정하여 nfs를 동작하게 한다.
/nfsroot localhost(rw,insecure,root_squash)
/nfsroot 192.168.11.*(rw,insecure,root_squash)
이런식으로 설정해 줄 수 있다.
/nfsroot는 서버의 nfs directory이며 localhost라든가 192.168.11.* 등의 address는 이 폴더(nfs directory)에 접근할 수 있는 권한을 줄 client를 말한다. 그리고 괄호안에 들어가있는 내용은 권한에 관련된 것이다.
3. 재시작
$ /etc/init.d/nfs restart
설정을 변경해주었으므로 재시작 한다.
4. 테스트 하기
잘 설치되었는지 보려면 테스트를 해본다.
$ mount -t nfs localhost:/nfsroot /temp
라고 입력하면 자기 컴퓨터의 /temp와 /nfsroot가 연결된다.
/nfsroot에 파일을 생성하거나 수정을 하면 /temp에도 똑같이 적용된다.
2008년 3월 28일 금요일
리눅스 커널 2.4 - scheduling 과정 중 context switching
/usr/src/linux-2.4.20-8/kernel/sched.c
/*
* context_switch – switch to the new MM and the new
* thread’s register state.
*/
static inline task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)
/*
* rq(runqueue_t)
* prev(task_t): 현재 실행되고 있는 process
* next(task_t): scheduling받아 이제 실행 될 process
*/
{
struct mm_struct *mm = next->mm;
struct mm_struct *oldmm = prev->active_mm;
if(unlikely(!mm)) //이전 process(prev)와 주소공간 공유
{
next->active_mm = oldmm;
//이전 process(prev)의 active_mm을 갖는다
atomic_inc(&oldmm->mm_count);
//oldmm의 reference count 증가
enter_lazy_tlb(oldmm, next, smp_processor_id()); //TLB설정
}
else //다른 주소공간을 가진 process일 경우
switch_mm(oldmm, mm, next);
//switch_mm을 호출하여 주소공간switch
if(unlikely(!prev->mm)) //현재process(prev)의 mm포인터가 null이라면
{
prev->active_mm = NULL;
//prev의 active_mm을 null로 만들어준다.
rq->prev_mm = oldmm;
}
/* Here we just switch the register state and the stack. */
switch_to(prev, next, prev); // CPU에 dependent한 매크로
return prev;
}
이 함수는 schedule() 함수에서 호출된다. scheduler가 다음 수행 될 process를 고르고 나서 호출하는 함수가 바로 이 context_switch함수이다. 현재 수행되고 있는 process의 정보와 다음 수행 될 process의 정보를 argument로 넘겨받는 context_switch함수는 가장먼저 process를 메모리 상에 올리는 일을 수행 한다. scheduling에 의해 선택되어 다음 번에 실행 될 process의 memory management(task_struct안의 mm_struct)가 NULL일 경우에는 수행되던 process의 주소공간을 공유하는 것이므로 이전의 process가 가진 mm_struct를 가지게 되고 mm_strcut의 구조체 포인터를 하나 증가시켜준다. NULL이 아닐 경우에는 수행 되던 process와 주소공간이 다른 것이므로 이 process가 가지고 있던 switch_mm이라는 함수를 호출한다. 여기서 switch_mm이 하는 일은 process의 주소 공간을 교체하는 것이다. 만약 수행중인 process(prev)의 mm이 NULL이라면 다른 누군가와 주소공간을 공유하고 있다는 뜻이다. 주소공간을 공유하더라도 이제 실행되지 않으면 active_mm을 NULL값을 주어 실행되지 않는 process임을 나타낸다. 그리고 runqueue의 prev_mm에 수행되던 process의 active_mm을 저장해 두었던 oldmm값을 넣는다. 이러한 주소공간 switching이 모두 일어난 후에 switch_to라는 매크로를 호출하여 레지스터의 저장과 저장되어있던 레지스터를 불러오는 일을 한다.
/usr/src/linux-2.4.20-8/include/asm-i386/system.h
#define switch_to(prev, next, last) do{
asm volatile(“pushl %%esi\n\t”
“pushl %%edi\n\t”
“pushl %%ebp\n\t” //레지스터 값 저장
“movl %%esp,%0\n\t” /* save ESP */
“movl %2,%%esp\n\t” /* restore ESP */
“movl $1f,%1\n\t” /* save EIP */
“pushl %3\n\t” /* restore EIP */
“jmp __switch_to\n” //__switch_to로 점프
“1:\t”
“popl %%ebp\n\t”
“popl %%edi\n\t”
“popl %%esi\n\t” //레지스터 값 로딩
:”=m” (prev->thread.esp), “=m” (prev->thread.eip)//출력
:”m” (next->thread.exp),”m”(next->thread.eip), “a”(prev), “d” (next)); //입력
}while(0)
이 부분은 CPU에 dependent한 부분이므로 CPU에 따라 달라질 수 있다. 이 매크로가 하는 일은 현재 실행중인 프로세서의 레지스터들을 저장하고 스케줄링 되어 실행 될 프로세서의 레지스터들을 가지고 오는 것이다. 먼저 실행중인 프로세서의 레지스터들을 stack에 저장하는데 그것이 esi, ebp, esp이다. thread_struct라는 struct의 0번째는 esp0가 있는데 이곳에 esp를 저장하고 2번째에 있는 esp값을 esp에 가져다 놓는다. 그리고 1번째에는 eip가 있는데 이 곳에 1f를 저장하여 다음번에 1f라는 곳에서부터 수행할 것을 알려준다. 3번째 값은 fs인데 이곳에 eip를 저장한다. 그리고 나서 __switch_to로 점프뛰는데 이 함수가 실행되고 난 후에는 바뀐 프로세서가 수행될 것이다. context switch가 완전히 다 일어나고 난 후에는 1: 이라고 되있는 leble부터 스케줄링 된 프로세스가 수행된다. 그래서 ebp, edi, esi가 차례대로 복구된다. m은 메모리를 의미하는데 “=”이 출력을, a 또는 d는 eax, edx레지스터를 뜻한다. 그래서 밑의 3줄 소스를 보면 prev(현재 실행중인 프로세스)는 eax레지스터에 저장되고 next(스케줄링 받은 프로세스)는 edx에 저장이 된다.
/usr/src/linux-2.4.20-8/arch/i386/kernel/process.c
void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
struct thread_struct *prev = &prev_p->thread,
*next = &next_p->thread;
int cpu = smp_processor_id();
struct tss_struct *tss = init_tss + cpu;
//현재 실행중인 프로세스 prev의 FPU상태를 저장
/* never put a printk in __switch_to … printk() calls wake_up*() indire ctly*/
unlazy_fpu(prev_p);
/* Reload esp0, LDT and the page table pointer: */
tss->esp0 = next0->esp0;
//스케줄링 받은 프로세스next의 esp0(커널 스택 주소)를 저장
/* Load the per-thread Thread-Local Storage descriptor. */
load_TLS(next, cpu);
/* Save away %fs and %gs. No need to save %es and %ds, as
those are always kernel segments while inside the kernel. */
asm volatile(“movl %%fs, %0”: “=m” (*(int *)&prev->fs));
asm volatile(“movl %%gs, %0”: “=m” (*(int *)&prev->gs));
//prev 프로세스의 fs와 gs레지스터 저장
/* Restore %fs and %gs if needed. */
if(unlikely(prev->fs | prev->gs | next->fs | next->gs)){
loadsegment(fs, next->fs);
loadsegment(gs, next->gs);
} //next 프로세스의 fs와 gs 레지스터 저장
/* Now maybe reload the debug registers */
if(unlikely(next->debugreg[7])) {
loaddebug(next, 0);
loaddebug(next, 1);
loaddebug(next, 2);
loaddebug(next, 3);
/* no 4 and 5 */
loaddebug(next, 6);
loaddebug(next, 7);
} //디버그 레지스터 로딩
if (unlikely(prev->ioperm || next->ioperm))
//IOperm시스템 콜일 경우에만 해당.
{
if(next->ioperm) {
memcpy(tss->io_bitmap, next->io_bitmap,
IO_BITMAP_SIZE*sizeof(unsigned long));
tss->bitmap = IO_BITMAP_OFFSET;
} else
tss->bitmap = INVALID_IO_BITMAP_OFFSET;
}
}
이 함수가 처음 하는 일은 현재 실행중인 프로세스의 상태를 저장하는 것이다. 그리고 스케줄링 받은 프로세서의 커널 스택 주소를 저장하는데 이 주소는 tss_struct라는 구조체의 esp0필드에 저장되어야 한다. 이 곳에서 CPU가 사용하는 커널 스택 주소가 결정되기 때문이다. 그 후에는 현재 수행중인 프로세스의 fs, gs 레지스터를 저장한다. fs와 gs는 데이터 이동시 사용자 세그먼트와 커널 세그먼트를 전환하는데 사용한다. 현재 수행중인 프로세스의 레지스터를 저장한 후에 할일은 당연히 다음 수행 될 프로세스의 레지스터를 로딩하는 것이다. 그리하여 fs, gs 레지스터를 로딩시키고 마지막으로 디버그 레지스터들을 로딩시킨다. 만약 프로세스가 IOperm시스템콜을 호출하였다면 그 프로세스가 I/O bitmap을 가지고 있는지 아닌지를 검사한다. 다음 수행될 프로세스가 I/O bitmap을 가지고 있다면 tss로 unsigned long크기만큼의 byte를 복사하고 그렇지 않다면 port 제어 명령어를 사용할 수 없다는 플래그를 설정한다.
2007년 11월 22일 목요일
proc, module programing
<< proc file system >>
proc file system은 파일과 프로세스를 통합하여 관리한다.
/proc 디렉토리에 가보면 프로세스나 하드웨어 정보를 담고있는 파일들을 볼 수가 있다.
이 파일들은 실제로 하드디스크 공간을 차지하지는 않으며, 사용자가 접근을 할 때 커널이 그 내용을 동적으로 만들어준다.
즉, user가 proc file system의 내용을 사용하려고 호출을 하면 커널이 그에 맞는 등록함수를 찾아서 사용할 수 있는 것있다.
그러므로 실제 data가 있는 것이 아니고 이 file system을 거쳐서 등록함수를 찾아내는 것이다. 이 등록함수들을 통하여 커널에 접근을 할 수 있으며, 이 함수들을 module이라고 한다.
결국, proc file system은 매개체의 역할을 하는 한마디로 trigger라고 할 수 있다.
그럼, 지금부터 module을 만들어서 proc을 사용해보도록 하자.
<< Module Programing >>
* 주의할 점 *
module programing은 kernel단의 programing이므로 자칫 잘못하다가는 시스템이 죽을 수 있으며, programing을 할 때 평소 사용하던 standard library는 사용할 수 없다.
1. 모듈 init 함수와 exit 함수.
module program에 꼭 필요한 것이 있는데 바로 init함수와 exit함수이다.
init함수는 module이 생성될 때 호출되는 것이며, exit함수는 module이 사라질 때 호출되는 것으로 C++의 생성자/소멸자와 비슷한 개념이다.
함수의 이름은 다음과 같이 지정해주어야만, init함수/exit함수로 인지할 수 있다.
//init 함수
int init_module(void)
{
// ... 필요한 일들을 수행
return 0;
}
//exit 함수
void cleanup_module(void)
{
// ... 필요한 일들을 수행
}
만약, 원하는 함수이름으로 지정을 하고 싶다면 원하는 이름으로 하되, 그 함수가 init함수/exit함수라는 것을 알려줄 수 있어야 한다.
init함수/exit함수를 지정해주는 매크로는 다음과 같다.
만약 init함수를 int myproc_init(void) 라고 선언하였고, exit함수를 void myproc_exit(void)라고 선언하였다면,
module_init(myproc_init);
module_exit(myproc_exit);
.. 이라고 사용한다.
init함수/exit함수만 알아도 hello world같은 쉬운 프로그래밍을 구현할 수 있다.
2. directory 만들기
내가 만든 모듈을 proc file system에 연결시켜서 사용하기 위해서는 proc file system에 directory가 필요하다.
이 directory로 접근을 하는 명령을 사용한다면 현재 programing하는 module을 가져올 것이다.
보통, directory는 init함수 안에서 생성하게 된다.
directory를 만들기 위해서는 proc_dir_entry라는 구조체가 필요하다.
전역변수로 struct proc_dir_entry형 변수를 하나 pointer로 선언한 후 함수를 호출한다.
static struct proc_dir_entry *dir; //전역변수로 선언
dir = proc_mkdir(MODULE_NAME, NULL);
여기서 말하는 MODULE_NAME은 스스로 지정해주어야 하는 문자열이며, 이 이름으로 directory를 생성한다.
directory생성에 실패할 경우 dir에 NULL값이 retrun되므로 확인하여 에러처리 할 수 있다.
3. read/write 콜백 함수
user가 read나 write를 위하여 module에 접근할 경우 read를 담당하는 함수와 write를 담당하는 함수가 필요하다.
사용자의 요구를 처리하기 위한 함수로 "cat"같은 명령어로 접근할 경우에는 read를 담당하는 콜백함수가 호출되고 "echo"같은 명령어로 접근할 경우에는 write를 담당하는 콜백함수가 호출된다.
그러니까, 결국은 콜백함수를 만들어 줘야 한다는 것이다.
읽기함수나 쓰기 함수의 이름은 어떤 것으로 해주어도 상관이 없지만 형식은 지켜주어야 한다.
읽기/쓰기 call back 함수의 형식은 다음과 같다.
int read_func(char* page, char** start, off_t off, int count, int* eof, void* data);
int write_func(struct file* file, const char *buffer, unsigned long count, void *data);
읽기 함수에서는 읽을 내용을 page에 읽어오고, 쓰기 함수에서는 buffer에 사용자가 쓴 데이터를 가져온다.
이러한 형식으로 선언된 call back함수에서는 read/write로 접근하였을 때 해주어야 할일을 구현하면 된다.
이 call back함수들을 위한 entry를 생성하고 등록을 시켜주는 일은 init함수에서 한다.
우선, READ를 위한 것 부터 보면 다음과 같다.
static struct proc_dir_entry *read_file; //전역변수로 선언
read_file = create_proc_read_entry("read", 0444, "MyProc", myproc_read, NULL);
init함수에서 create_proc_read_entry함수를 호출하여 entry생성과 등록을 시켜준다. 읽기 전용으로 "read"파일을 MyProc 디렉토리 안에 만드는 것이다. 이 때 MyProc은 위에서 생성한 directory (MODULE_NAME)와 이름이 같아야 한다. 0444는 접근 권한이며 myproc_read라는 함수를 call back함수로 등록시켜준다.
create_proc_read_entry라는 함수는 wrapper함수이다. 이 함수 안에서도 결국 create_proc_entry를 호출을 하여 사용하지만 읽기 전용 proc파일을 생성하기 쉽게 하기 위해서 사용한다.
이 wrapper함수도 위에 directory 생성 함수와 마찬가지로 read_file로 return된 값이 NULL이라면 entry생성에 실패한 것이므로 에러처리를 해줄 수 있다.
다음은 WRITE를 위한 함수를 보자.
static struct proc_dir_entry *write_file; //전역변수로 선언
write_file = create_proc_entry("write", 0644, "MyProc");
init함수에서 create_proc_entry를 호출하여 entry를 생성하고 등록시킨다.
읽기/쓰기 전용으로 "write"파일을 MyProc디렉토리 안에 만들게 된다.
create_proc_read_entry 안에서도 이 함수를 호출하게 되나 wrapper함수를 사용하면 더 좋은 점은 읽기전용에 대한 설정들을 자동으로 해준다는 것이다.
create_proc_entry를 호출하게 되면 proc_dir_entry 구조체에 있는 값들을 설정을 해주어야 한다. wrapper함수를 사용하면 call back함수를 자동으로 연결시켜주지만, 이 함수는 그렇지 못하므로 그 연결을 해주기 위한 설정이 필요한 것이다.
write_file->read_proc = proc_read;
write_file->write_proc = proc_write;
//call back함수를 연결해 주어야 한다.
4. 몇 가지 유의 사항
proc_dir_entry 구조체를 생성할 때 성공적으로 만들어지지 못하면 NULL값이 return되므로 에러처리를 해준다.
proc_dir_entry 구조체를 성공적으로 생성한 후에는 구조체에 있는 owner의 값에 THIS_MODULE을 넣어주어야 제대로 동작한다.
즉, 위에 write_file을 예로 들면,
write_file->owner = THIS_MODULE 이런식으로 해주어야 한다.
init함수와 read/write call back함수에는 반드시 return값이 필요하다. 성공을 했을 경우에는 return 0를 해주자.
read/write함수에서는 데이타의 길이를 return하는 경우도 있다.
5. 모듈 컴파일
call back함수와 init/exit함수를 다 구현하였다면 컴파일을 해보자.
2.4커널 버전을 사용한다면 간단한 컴파일 명령으로 컴파일이 가능하다.
$ gcc -c -D__KERNEL__ -DMODULE -O test.c
그러나, 2.6버전의 커널을 사용한다면 Makefile이 반드시 필요하다.
$ vi Makefile
Makefile을 만들어보자.
obj-m := test.o //object file 이름이다.
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.ko
rm -rf *.mod
rm -rf *.o
rm -rf *.cmd
.. 이것이 간단한 Makefile이다.
그리고 나서 컴파일을 하면 여러개의 파일이 마구 생긴다.
그 중에서 우리가 필요한 파일은 test.ko파일이다. (2.4커널버전에서는 test.o)
이것이 바로 module파일이다.
6. module 생성
$ lsmod
.. 라고 명령어를 실행시키면 지금 올라와 있는 module들이 보여진다.
이 곳에 만들어 놓은 module을 올려보자.
$ insmod test.ko
.. 이렇게 하면 만들어 놓은 test라는 이름으로 module이 올라가면서 /proc 아래에 프로그래밍 할 때 MODULE_NAME으로 주어진 이름으로 directory가 하나 생성된다.
$ cat /proc/MyProc/read
.. 라고 하면 read파일에 읽기로 접근한다.
$ echo "test" > /proc/MyProc/write
.. 라고 하면 write파일에 쓰기로 접근한다.
하는일은 call back함수에서 지정한 일을 하게 된다.
module을 삭제하고 싶으면 다음 명령어를 실행시킨다.
$ rmmod test
2007년 11월 15일 목요일
tftp 설치
우선, tftp 패키지를 인스톨 해야한다.
$ yum install tftp-server
인스톨이 되면서 tftp가 깔리는 동시에 루트에 tftproot 폴더가 생성된다.
2. 설정
/etc/xinetd.d/ 에 가보면 tftp라는 파일이 있다.
그 파일을 열어보면 tftp에 대한 설정이 저장되어 있는데 처음 install을 했을 경우, tftp service가 disable되어있다. 그것을 "no"로 바꿔주면 enable된다.
3. 재시작
$ /sbin/service xinetd restart
설정을 변경해주었으므로 재시작 한다.
4. 테스트하기
잘 설치되었는지 보려면 테스트를 해본다.
$ tftp localhost
라고 입력하면 자기 컴퓨터의 tftp server로 접속하게 된다.
기본적으로 루트에 생성된 tftproot폴더로 접속된다. 아무 파일이나 다운받아보자.
tftp> get test.txt (물론 파일을 다운받으려면 그 폴더에 이 파일이 있어야한다.)
tftp> quit
quit한 뒤 현재 폴더에 다운로드 받은 파일이 있나 확인해본다.
잘 다운받아졌다면, tftp설치 complete!!
2007년 11월 13일 화요일
samba server 사용
samba server에 user추가
samba server에 user를 추가하기 위해서는 일단 리눅스 계정이 있어야만 한다.
그러므로 리눅스 계정이 있다면 그 계정으로 samba server를 만들면 되고, 아니면 리눅스 계정부터 만들어 주어야한다.
$ useradd test
test라는 이름으로 linux계정을 만드는 명령어 이다. 그리고 password를 지정해주어야 하는데 다음과 같다.
$ passwd test
test라는 계정에 password를 지정해줄 수 있게 한다.
passwd는 확인을 하기위해서 두번을 입력받아 저장한다.
이제 samba server에 이 test라는 녀석을 user로 추가해보자.
예전 버전에서는 smbadduser라는 명령어를 썼다고 하던데, 최신버전에서는 그냥 하면 되더라......;;;;;
$ smbpasswd -a test
라고 하면 test라는 계정을 samba server에 추가하면서 passwd설정까지 같이 해주는 것이다. 옵션에 따라서 추가인지 삭제인지 혹은 그룹을 지정하는 것 까지 가능하다.
이 명령어를 사용하면 test라는 계정을 samba server에 추가하면서 samba server에서 사용할 password를 물어본다.
이 때도 마찬가지로 password를 두 번 입력받아 저장한다.
"Added user test." 라는 문구가 뜨면 성공이다.
samba server 접속
server에 접속을 하기 위해서는 smbclient가 필요한데, 없으면 깔아야 한다.
$ yum install samba-client
하면 install이 되고 samba-client가 깔린다.
그리고 samba server에 접속한다.
$ smbclient //IP주소/homeDir -U ID
이런식으로 사용한다.
예를들어 127.0.0.1에 접속하려 하고 내 계정이 test라면,
$ smbclient //127.0.0.1/test -U test 라고 사용한다.
password를 치고 접속을 하면 자신의 directory가 보인다.
프롬프트도 바뀌는데
smb: \>
이렇게 뜬다.
이 samba server에서 받고 싶은 파일이 있다면 get명령어를 사용해서 파일을 받으면 된다.
smb: \> get test.txt
samba server에서 사용할수 있는 모든 명령어는 ?를 치면 다 나온다.
smb: \> ?
2007년 10월 25일 목요일
커널 컴파일
1. 커널 다운로드 받기
$ ftp ftp.kernel.org
login은 anonymous로 한다.
ftp> mget (받을 파일이름)
ftp> quit
현재 폴더에 커널이 받아진 걸 볼 수 있다.
그걸 /usr/src/ 로 옮겨서 압축을 해제한다.
$ tar xvf (파일이름)
2. 커널 컴파일
$cd /usr/src/linux-버전
$ make mrproper
$ make menuconfig
커널 옵션 설정. 필요한것들만 바꾼다.
$ make dep
$ make bzImage
$ make module
크로스 컴파일러 설치
리눅스환경에서 arm 기반 프로그램을 컴파일해서 올리자면, arm용 (arm9기반이니까) 컴파일러가 필요한데-
이 때 해야하는 작업이 크로스 컴파일이다.
크로스컴파일. 말은 그럴싸하니 멋있지만, 삽질의 장본인이다. (그앙!)
그럼 우선, 크로스컴파일을 해보자.
<< 크로스컴파일러 깔기 >>
1. 다운받는다.
어디서고 상관없지만, 나는 arm.linux.org.uk에서 받았다...
$ wget http://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross-3.2.tar.bz2
arm용으로 3.2버전을 받았다.
압축을 풀고, 원하는 곳으로 옮긴다.
압축을 풀면 나오는 arm이라는 폴더를 /usr/local/ 에 두었다. (그냥 내맘-_-)
2. 패스설정한다.
그리고 나서 .bash_profile을 고쳐주어야 한다. 그렇지 않으면 command를 찾지 못할 것이다.
.bash_profile은 ~/ 경로를 찾으면 있다.
다른 방법으로 cd 치고 엔터를 누르면 이동하는 경로이다.
보통 ls로는 보이지 않는 파일이고, 파일목록으로 보고 싶으면 ls -al을 하면 보인다.
vi를 이용해서 편집을 한다.
PATH 라고 되어 있는 부분을 찾는다.
보통은
PATH=$PATH:$HOME/bin 이라고 되있을 건데, 여기다가 크로스컴파일러 깐 곳의 path를 입력해준다.
PATH=/usr/local/arm/bin:$PATH:$HOME/bin
bin폴더 아래에 가보면 크로스 컴파일러가 가득한 것을 볼 수 있다.
크로스 컴파일러가 있는 경로를 넣어주면 되는 것이다.
마지막으로 바뀐 bash_profile을 적용시켜주어야 한다.
$ source .bash_profile
그리고 나서 확인을 해보려면, command를 입력해보면 된다.
arm-linux-gcc 라고 입력하고 엔터를 쳤을 때,
input file이 없다고 에러메세지가 뜨면 제대로 경로를 잡은 것이고,
그렇지 않고 없는 command라고 뜬다면 제대로 경로를 잡지 못한것이다.