본문 바로가기
카테고리 없음

리눅스 시스템 부팅 시 오픈하는 소스파일

by 혜룐 2015. 11. 10.

( 라우팅 추가를 rc.local에 설정했는데 실행이 되지 않았다..10.5.5.0/24 로 해서인데 netmask 255.255.255.0 으로 해야 한다.. )
grub이 grub.conf를 읽어 부팅을 결정한다.
grub 이 불러들인 커널은 압축된 이미지로 메모리에 압축된 이미지를 풀고 수행을 시작한다. 로드된 커널이 부팅될때 필요한 코드는 다음과 같다.
root@lhr:/Linux_source/linux-2.6.32/arch/x86/boot># ls
Makefile bitops.h compressed edd.c mca.c pm.c setup.ld version.c video-vesa.c
a20.c boot.h copy.S header.S memory.c pmjump.S string.c vesa.h video-vga.c
apm.c cmdline.c cpu.c install.sh mkcpustr.c printf.c tools video-bios.c video.c
bioscall.S code16gcc.h cpucheck.c main.c mtools.conf.in regs.c tty.c video-mode.c video.h
커널 이미지가 호출되면 먼저 setup.c의 start()가 수행된다. 
.S 확장자는 엄셈 블리어로 작성되어있다. 
vi /Linux_source/linux-2.6.32/init/main.c 소스를 열어보면 #include<linux/start_kernel.h>이렇게 include 해서 해당 헤더파일을 사용한다.
root@lhr:/Linux_source/linux-2.6.32/arch/x86/boot># vi /Linux_source/linux-2.6.32/include/linux/start_kernel.h
#ifndef _LINUX_START_KERNEL_H
#define _LINUX_START_KERNEL_H
#include<linux/linkage.h>
#include<linux/init.h>
/* Define the prototype for start_kernel here, rather than cluttering
up something else. */
extern asmlinkage void __init start_kernel(void); # main.c에 호출되는 함수명
#endif /* _LINUX_START_KERNEL_H */
리눅스 시스템 부팅시 커널이 올라오면 커널은 우선 루트 파일 시스템(/)을 read-only 형태로 마운트하고 검사 후 이상이 없으면 read-write로 재마운트한다. 
그리고 모든 프로세서의 어머니라고 볼 수 있는 init 프로세서를 실행시킨다. 이 init 프로세서가 특정 파일을 핸들링 하면서 부팅의 단계가 시작된다. 
순서
내용
설명
1
init 프로세서의 실행
init 프로세서는 /etc/inittab이라는 설정파일을 읽어서 설정된 내용대로 부팅절차를 시작한다.
2
/etc/rc.d/rc.sysinit 스크립트 실행
/etc/inittab의 내용에 의하여 먼저 시스템을 초기화 하기 위해서 /etc/rc.d/rc.sysinit 스크립트 파일을 실행시킨다. 여기서는 호스트명 설정, 스와핑 설정, 시스템 점검, 커널 모듈 로딩 등 많은 일을 한다.
3
/etc/rc 스크립트 실행
rc.sysinit에 의해 시스템이 초기화 되었으면 /etc/rc 스크립트를 통해서 기본 실행레벨별 등록된 데몬 프로그램을 실행시킨다.
4
/etc/rc.d/rc.local 스크립트 실행
실행레벨 2, 3, 5에서의 마지막에 이 스크립트가 실행된다.
5
login이나 X-Window 구동
마지막으로 getty이나 xdm을 통해서 해당 실행레벨별로 login과정이나 X-Window를 구동시킨다.
root@lhr:/data># cat /etc/inittab | grep -v ^#
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
x:5:respawn:/etc/X11/prefdm -nodaemon
root@lhr:/data># more /etc/rc.d/rc.sysinit 
#!/bin/bash
#
# /etc/rc.d/rc.sysinit - run once at boot time
#
-->네트워크
if [ -f /etc/sysconfig/network ]; then
. /etc/sysconfig/network
fi
-->스와핑
if [ -x /etc/init.d/diskdump ]; then
/etc/init.d/diskdump swapsavecore
fi 
# Start up swapping.
update_boot_stage RCswap
action $"Enabling swap space: " swapon -a -e
-->커널모듈로딩
load_module $module
root@lhr:/data># vi /etc/rc.d/rc
rc rc.local rc.sysinit rc0.d/ rc1.d/ rc2.d/ rc3.d/ rc4.d/ rc5.d/ rc6.d/
root@lhr:/data># vi /etc/rc.d/rc.local 
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
touch /var/lock/subsys/local
ethtool -s eth0 speed 1000 duplex full autoneg off
ethtool -s eth1 speed 1000 duplex full autoneg off
위의 부팅과정을 읽어보면 종종 실행레벨(Runlevel)이라는 말이 나온다. 이 말은 리눅스의 여러가지 상태를 나타내는것으로 크게 6개의 실행레벨로 나뉜다. 
실행레벨
설명
0
시스템의 중지에 사용됨
1
단일사용자모드(Single User Mode)로서 윈도우의 안전모드와 유사한 개념임
2
사용되지 않음
3
다중사용자모드(Multiuser)로 여러 사용자가 사용할 수 있도록 시스템을 구성
4
사용되지 않음
5
X-Window 시스템 실행 모드
6
시스템 재부팅 모드
일반적으로는 실행레벨 3과 5를 많이 사용한다. 초기의 리눅스는 실행모드 3이 기본모드였지만, 레드헷 6.0으로 접어들면서 시작화면을 X-Window를 채택한 실행모드 5가 많이 쓰이고 있다. 이 항목은 /etc/inittab의 다음 항목에서 설정할 수 있다. 
id:3:initdefault:
즉, 위의 예에서는 이 시스템은 부팅시 실행레벨 3으로부터 시스템이 시작한다는 뜻이 된다. 
rc.sysinit가 실행이 되고난 후는 각 해당레벨별로 /etc/rc.d/rc.<실행레벨>에 있는 모든 스크립트가 실행된다. 즉, 실행레벨 3이라면 /etc/rc.d/rc.3 디렉토리의 모든 스크립트 파일이 실행이 되고, 실행레벨 3에서 실행시키고 싶은 특정 데몬이 있다면 그 해당 디렉토리에 등록을 시켜주면 된다. 
하지만 실제로 /etc/rc.d/rc.<실행레벨>에는 심볼릭링크 파일만 담고 있을뿐 rc 스크립트에 의해서 실행될 모든 스크립트 파일의 원본은 /etc/rc.d/init.d 디렉토리에 담고 있다. /etc/rc.d/rc.<실행레벨>은 /etc/rc.d/init.d의 심볼릭링크만 있을뿐이다. 
즉, 새로운 서비스를 추가하고자 한다면 /etc/rc.d/init.d에 실행파일과 같은 이름으로 특정 형식에 맞추어서 스크립트 파일을 만든 후 실행을 원하는 실행레벨 디렉토리에서 심볼릭 링크를 만들어 주면 된다. 하지만 이런 일들을 직접 해줄 필요는 없다. 이미 리눅스에서는 이러한 실행레벨을 관리해줄 수 있는 수많은 프로그램이 공개가 되어 있기 때문이다. 
그리고 이런 rc 스크립트의 내용은 실행뿐만 아니라 종료의 내용까지 포함하고 있다.
위에서 추가와 삭제에 관해서 잠깐 언급을 하였다. 하지만 실제로 실행레벨을 관리할 때는 수작업보다는 전문적인 관리툴을 많이 이용한다. 관리툴은 일반적인 쉘용 프로그램 및 X-Window용이 있는데, X-Window용의 관리 프로그램이 사용하기 편할것이다. 유명한 프로그램으로는 linuxconf가 있고 그외 자신의 배포본의 메뉴를 뒤지다 보면 이런 일을 할 수 있는 프로그램들이 등록되어 있다. 사용방법은 위의 내부구조를 이해했으면 큰 무리없이 사용할 수 있을것이라고 생각한다.
하지만 간단한 데몬프로그램이나 기타 프로그램을 이런식으로 등록한다는건 좀 번거로운게 사실이다. 이때는 /etc/rc.d/rc.local 파일을 많이 이용한다. 이 파일의 마지막에 자신이 원하는 실행파일이나 명령어를 써주기만 하더라도 항상 부팅할 때 마다 자동으로 실행이 된다. 그러나 알짜리눅스에서는 여기에 한가지 과정을 더 추가하고 있다. 바로 /etc/rc.d/rc.local.mine 파일이다. 알짜리눅스의 /etc/rc.d/rc.local의 마지막 부분을 보면 다음과 같은 행이 들어가 있다. 
if [ -x /etc/rc.d/rc.local.mine ]; then. /etc/rc.d/rc.local.mine fi
간단한 쉘스크립트로 /etc/rc.d/rc.local.mine 파일이 있다면 이 파일을 실행시키라는 명령이다. 즉, 알짜에서는 rc.local 파일이 아닌 rc.local.mine 파일에 사용자 정의 데몬들을 등록시키기를 권장하고 있다. 이유는 많은 RPM 데몬패키지들은 설치시 기존의 rc.local 파일을 백업하고 자신의 rc.local 파일로 대처하기 때문에 자신이 수정해 놓은 부분을 RPM 설치 후 하나 하나 다시 수정해주어야 하는 단점이 있다. 그래서 rc.local.mine 파일을 분리하고 RPM 데몬을 설치 후 위의 3라인만 추가시키면 손쉽게 자신의 수정부분을 추가할 수 있다는 장점이 있다. 하지만 이것 역시 미봉책일뿐 RPM으로 패키징된 데몬을 두가지 이상 설치하면 역시 똑 같은 문제점에 부딛히게 된다. 이것을 해결할 근본적인 해결책은 RPM으로 배포하는 데몬들은 rc.local을 사용하지 않고, rc.<실행레벨>스크립트를 이용하는 방법이겠다.