[LFS_prj] 06 Ubutu porting

How to apply Ubuntu root file system on Zynq

LFS 시스템 빌드를 위한 cross tool chain의 설정과정을 다룬다.

Techical note

LFS 시스템의 빌드 단계는 아래의 단계를 따른다

Stage Build Host Target Action
1 pc pc lfs Build cross-compiler cc1 using cc-pc on pc.
2 pc lfs lfs Build compiler cc-lfs using cc1 on pc.
3 lfs lfs lfs Rebuild and test cc-lfs using cc-lfs on lfs

여기서 1단계와 2단계가 cross compiler를 구축하는 단계이고 3단계는 chroot와 cross compiler를 이용한 LFS 시스템을 만드는 단계이다. cross compiler를 만드는 단계가 2단계로 구분되어 있는 이유는 하기와 같이 설명하고 있다.

  • C언어는 단순컴파일러가 아니라 표준 라이브러리(glib)도 정의하는데 이는 cc1으로 컴파일되어야 함
  • 그런데 컴파일러는 내부 라이브러리 libgcc를 이용해 컴파일하는데 이는 glib에 연결되어 있어야함
  • 이 상호 의존 문제를 해결하기 위해 먼저 cc1 및 libgcc(스레드,예외처리 일부 기능이 부족한)를 만들고 이를 이용해 glib을 만듬(glib은 성능저하 없음)
  • 그 다음 2단계에서 cc1을 이용해 cc-lfs를 만드며 이때 libgcc 및 llibstdc++도 다시 만듬

그리고 3단계(chroot) 환경에서 기존에 만든 패키지가 있음에도 다시 모든 패키지를 빌드하는데 이는 LSF를 안정적으로 만들어 준다.(2단계에서 만든 패키지들이 몇가지 디펜던시가 부족하므로)

(이해하기 좀 빡세다…해보면 이해간다는데 해봐도 머리속이 클리어하지 않다.)

Compiling a Cross-Toolchain

위의 1단계, cc1을 빌드하고 glib을 만든다. 그리고 cc-lfs도 만들 수 있도록 libstdc++도 추출함

  1. Binutils-2.40 - Pass 1

    • linker, an assembler, and other tools for handling object files
    • –prefix=$LFS/tools, –with-sysroot=$LFS 옵션으로 볼 때 host환경에서 쓴다는 것을 알 수 있다.
  2. GCC-12.2.0 - Pass 1

    • -prefix=$LFS/tools, –with-sysroot=$LFS 옵션으로 볼 때 host환경에서 사용
    • –disable-shared에서 내부 라이브러리를 정적으로 쓰도록 함, 호스트의 동적 라이브러리로 인한 문제 차단
    • –disable-libstdcxx 등 : 위에서 설명한 일부기능이 부족한 cc1이 됨
  3. Linux-6.1.11 API Headers

    • 리눅스 커널에서 Glibc에 쓰이는 커널 API인 리눅스 API 헤더를 추출
  4. Glibc-2.37

    • Glibc 패키지는 메인 C 라이브러리를 포함하고 있다. 이 라이브러리는 메모리 할당, 디렉토리 검색, 파일 열기 및 닫기, 파일 읽기 및 쓰기, 문자열 처리, 패턴 대조, 산술 등의 기본 루틴을 제공한다
    • –prefix=/usr 로 볼때 빌드된 것이 LFS 시스템 상에서 사용됨을 알 수 있다.
    • –host=$LFS_TGT, –build=$(../scripts/config.guess) 는 이전의 gcc와 binutil등을 이용해서 크로스 컴파일함
  5. Libstdc++ from GCC-12.2.0

    • c++을 설치하기 위해서 Libstdc++가 필요한데 Glibc에 디펜던시를 가지므로 gcc 설치 시 설치하지 않았다.
    • Glibc와 같이 –prefix=/usr, –host=$LFS_TGT, –build=$(../scripts/config.guess) 구성을 사용

Cross Compiling Temporary Tools

위 기술노트의 2단계, cc-lfs를 구축한다.

  1. M4-1.4.19
    • 매크로 처리기
  2. Ncurses-6.4
    • 문자 화면의 터미널 독립적 처리를 위한 라이브러리를 포함(clear, tab 같은)
  3. Bash-5.2.15
    • 배쉬 쉘
  4. Coreutils-9.1
    • 기본적인 시스템 특성을 보여주고 설정하기 위한 유틸리티(cat, chmod, cp, dd 등등)
  5. Diffutils-3.9
    • diff 유틸
  6. File-5.44
    • file 명령어 util
  7. Findutils-4.9.0
    • Findutils 패키지는 파일을 찾는 프로그램을 포함(find 등)
  8. Gawk-5.2.1
    • 텍스트 편집에 최적화된 스크립트 언어
  9. Grep-3.8
  10. Gzip-1.12
  11. Make-4.4
  12. Patch-2.7.6
  13. Sed-4.9
  14. Tar-1.34
  15. Xz-5.4.1
  16. Binutils-2.40 - Pass 2
  17. GCC-12.2.0 - Pass 2

Entering Chroot and Building Additional Temporary Tools

위의 빌드를 위한 임시 시스템에서 필요한 몇가지 패키지를 chroot의 분리된 환경에서 설치한다.

  • 상기 패키지를 host환경이 아닌 LFS 환경에서 설치하는 이유는 나와있지 않다.
  • LFS ver9에서는 chroot로 LFS 환경으로 들어가기 이전에 모든 빌드 시스템 구축을 끝낸다.(이게 더 이해가 쉬운듯)

Entering Chroot env and make VFS

현재까지 만들어진 파일 시스템은 lfs 소유인데 이는 다른 유저가 파일을 조작할 권리를 얻을 수 있으므로 소유자를 root로 변환

1
2
3
4
chown -R root:root $LFS/{usr,lib,var,etc,bin,sbin,tools}
case $(uname -m) in
  x86_64) chown -R root:root $LFS/lib64 ;;
esac

/dev 등 필요한 가상 커널 파일 시스템을 생성한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mkdir -pv $LFS/{dev,proc,sys,run}
mount -v --bind /dev $LFS/dev

mount -v --bind /dev/pts $LFS/dev/pts
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
mount -vt tmpfs tmpfs $LFS/run

if [ -h $LFS/dev/shm ]; then
  mkdir -pv $LFS/$(readlink $LFS/dev/shm)
else
  mount -t tmpfs -o nosuid,nodev tmpfs $LFS/dev/shm
fi

chroot를 이용하여 LFS환경으로 진입한다

1
2
3
4
5
6
chroot "$LFS" /usr/bin/env -i   \
    HOME=/root                  \
    TERM="$TERM"                \
    PS1='(lfs chroot) \u:\w\$ ' \
    PATH=/usr/bin:/usr/sbin     \
    /bin/bash --login

리눅스 표준 디렉토리 트리를 생성한다(리눅스 파일 시스템 계층 표준 기반)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
mkdir -pv /{boot,home,mnt,opt,srv}

mkdir -pv /etc/{opt,sysconfig}
mkdir -pv /lib/firmware
mkdir -pv /media/{floppy,cdrom}
mkdir -pv /usr/{,local/}{include,src}
mkdir -pv /usr/local/{bin,lib,sbin}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -pv /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -pv /usr/{,local/}share/man/man{1..8}
mkdir -pv /var/{cache,local,log,mail,opt,spool}
mkdir -pv /var/lib/{color,misc,locate}

ln -sfv /run /var/run
ln -sfv /run/lock /var/lock

install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp

리눅스는 마운트된 파일시스템의 리스트를 /etc/mtab에 관리하고 이를 /proc에 노출시키므로 이를 위한 심볼릭 링크를 생성

  • mtab은 mount command에 의해 자동갱신됨, fstab은 부팅 시 마운트할 목록
1
ln -sv /proc/self/mounts /etc/mtab

host 파일과 /etc/passwd. /etc/group을 생성한다. 필요 시 테스트를 위한 테스트 그룹도 생성하고 재로그인 한다. 생성된 그룹은 어떤 표준에도 속하지 않는 Udev 구성의 요구사항에 의해 만들어진 그룹이다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
cat > /etc/hosts << EOF
127.0.0.1  localhost $(hostname)
::1        localhost
EOF

cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/usr/bin/false
daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false
systemd-journal-gateway:x:73:73:systemd Journal Gateway:/:/usr/bin/false
systemd-journal-remote:x:74:74:systemd Journal Remote:/:/usr/bin/false
systemd-journal-upload:x:75:75:systemd Journal Upload:/:/usr/bin/false
systemd-network:x:76:76:systemd Network Management:/:/usr/bin/false
systemd-resolve:x:77:77:systemd Resolver:/:/usr/bin/false
systemd-timesync:x:78:78:systemd Time Synchronization:/:/usr/bin/false
systemd-coredump:x:79:79:systemd Core Dumper:/:/usr/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false
systemd-oom:x:81:81:systemd Out Of Memory Daemon:/:/usr/bin/false
nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false
EOF

cat > /etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
systemd-journal:x:23:
input:x:24:
mail:x:34:
kvm:x:61:
systemd-journal-gateway:x:73:
systemd-journal-remote:x:74:
systemd-journal-upload:x:75:
systemd-network:x:76:
systemd-resolve:x:77:
systemd-timesync:x:78:
systemd-coredump:x:79:
uuidd:x:80:
systemd-oom:x:81:
wheel:x:97:
users:x:999:
nogroup:x:65534:
EOF

exec /usr/bin/bash --login

마지막으로 login, agetty 및 init 들은 로그파일이 존재하지 않으면 로그를 남기지 않으므로 파일을 미리 생성해준다.

1
2
3
4
touch /var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664  /var/log/lastlog
chmod -v 600  /var/log/btmp

Building Additional Temporary Tools

하기 패키지를 설치한다.

  1. Gettext-0.21.1
    • 다국어화와 현지화를 위한 유틸리티가 포함, 프로그램을 현지 언어를 지원하도록 컴파일 할 수 있음
  2. Bison-3.8.2
    • 파서 생성기가 포함(?)
  3. Perl-5.36.0
  4. Python-3.11.2
  5. Texinfo-7.0.2
    • info 페이지를 읽고, 쓰고, 변환하는 프로그램(man보다 자세하다고 함)
  6. Util-linux-2.38.1
    • 파일 시스템, 콘솔, 파티션 및 메시지를 처리하는 유틸리티가 포함된 패키지

Cleaning and Backup

툴체인 셋업이 완료되었으므로 필요하다면 현재구성을 백업하도록 하자. 상세 내용은 메뉴얼 참조

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy