운영체제 기본/x86-64 Linux의 BIOS 부팅/GDT와 LDT 초기화: 두 판 사이의 차이
잔글 관리자님이 운영체제 기본/x86-64 Linux의 부팅/GDT와 LDT 초기화 문서를 운영체제 기본/x86-64 Linux의 BIOS 부팅/GDT와 LDT 초기화 문서로 이동했습니다: x86-64 전용 각론의 아키텍처와 장치·부팅 범위를 제목에 명시 |
BIOS 부팅·i8042 키보드 각론의 새 문서명으로 내부 링크 갱신 |
||
| 1번째 줄: | 1번째 줄: | ||
[[운영체제 기본/x86-64 Linux의 부팅|부팅 목차]] · 이전: [[운영체제 기본/x86-64 Linux의 부팅/진입 규약과 압축 해제|진입 규약과 압축 해제]] · 다음: [[운영체제 기본/x86-64 Linux의 부팅/커널 초기화|커널 초기화]] | [[운영체제 기본/x86-64 Linux의 BIOS 부팅|부팅 목차]] · 이전: [[운영체제 기본/x86-64 Linux의 BIOS 부팅/진입 규약과 압축 해제|진입 규약과 압축 해제]] · 다음: [[운영체제 기본/x86-64 Linux의 BIOS 부팅/커널 초기화|커널 초기화]] | ||
BIOS에서 출발해 GRUB의 <code>linux</code> 명령으로 Linux v6.12 x86-64 bzImage를 부팅하는 경로에서는, GRUB이 32비트 보호 모드의 실행 환경을 만들어 압축 해제기의 <code>startup_32</code>에 제어를 넘긴다. 이 시점에 이미 GDT가 있어야 하지만, 그것이 이후 Linux가 계속 사용할 GDT라는 뜻은 아니다. Linux는 '''실행 모드의 전환, 압축 해제기의 이동, 커널 가상 주소로의 전환, CPU별 자료구조의 설치'''에 맞추어 GDTR을 여러 번 갱신한다. GRUB이 준비하는 초기 CPU 상태는 [[운영체제 기본/x86-64 Linux의 부팅/GRUB에서 커널로|GRUB에서 커널로]]에서 이어진다.<ref name="gdt-boot">[https://docs.kernel.org/6.12/arch/x86/boot.html Linux v6.12, The Linux/x86 Boot Protocol], 32-bit Boot Protocol.</ref> | BIOS에서 출발해 GRUB의 <code>linux</code> 명령으로 Linux v6.12 x86-64 bzImage를 부팅하는 경로에서는, GRUB이 32비트 보호 모드의 실행 환경을 만들어 압축 해제기의 <code>startup_32</code>에 제어를 넘긴다. 이 시점에 이미 GDT가 있어야 하지만, 그것이 이후 Linux가 계속 사용할 GDT라는 뜻은 아니다. Linux는 '''실행 모드의 전환, 압축 해제기의 이동, 커널 가상 주소로의 전환, CPU별 자료구조의 설치'''에 맞추어 GDTR을 여러 번 갱신한다. GRUB이 준비하는 초기 CPU 상태는 [[운영체제 기본/x86-64 Linux의 BIOS 부팅/GRUB에서 커널로|GRUB에서 커널로]]에서 이어진다.<ref name="gdt-boot">[https://docs.kernel.org/6.12/arch/x86/boot.html Linux v6.12, The Linux/x86 Boot Protocol], 32-bit Boot Protocol.</ref> | ||
== 디스크립터와 선택자, 테이블 레지스터 == | == 디스크립터와 선택자, 테이블 레지스터 == | ||
| 75번째 줄: | 75번째 줄: | ||
<code>gdt_page</code>는 <code>arch/x86/kernel/cpu/common.c</code>에서 <code>DEFINE_PER_CPU_PAGE_ALIGNED</code>로 선언된다. 32·64비트 커널 코드와 사용자 코드, 커널·사용자 데이터 항목 등은 정적 초기값을 가진다. “CPU별 GDT”라고 해서 처음 명령부터 동적으로 할당된 최종 CPU별 메모리를 쓰는 것은 아니다. 초기 부트 CPU용 영역에서 시작하고, <code>start_kernel()</code>의 <code>setup_per_cpu_areas()</code> 단계에서 정규 CPU별 영역을 준비한 뒤 부트 CPU도 <code>switch_gdt_and_percpu_base()</code>로 그 영역으로 옮겨 간다.<ref name="gdt-common">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/common.c?h=v6.12 Linux v6.12, arch/x86/kernel/cpu/common.c], gdt_page, cpu_init_exception_handling(), cpu_init(), load_fixmap_gdt().</ref><ref name="gdt-percpu">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/setup_percpu.c?h=v6.12 Linux v6.12, arch/x86/kernel/setup_percpu.c], setup_per_cpu_areas().</ref> | <code>gdt_page</code>는 <code>arch/x86/kernel/cpu/common.c</code>에서 <code>DEFINE_PER_CPU_PAGE_ALIGNED</code>로 선언된다. 32·64비트 커널 코드와 사용자 코드, 커널·사용자 데이터 항목 등은 정적 초기값을 가진다. “CPU별 GDT”라고 해서 처음 명령부터 동적으로 할당된 최종 CPU별 메모리를 쓰는 것은 아니다. 초기 부트 CPU용 영역에서 시작하고, <code>start_kernel()</code>의 <code>setup_per_cpu_areas()</code> 단계에서 정규 CPU별 영역을 준비한 뒤 부트 CPU도 <code>switch_gdt_and_percpu_base()</code>로 그 영역으로 옮겨 간다.<ref name="gdt-common">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/common.c?h=v6.12 Linux v6.12, arch/x86/kernel/cpu/common.c], gdt_page, cpu_init_exception_handling(), cpu_init(), load_fixmap_gdt().</ref><ref name="gdt-percpu">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/setup_percpu.c?h=v6.12 Linux v6.12, arch/x86/kernel/setup_percpu.c], setup_per_cpu_areas().</ref> | ||
이 순서 이후 <code>trap_init()</code>이 CPU entry area와 정상 운영용 TSS를 준비한다. 다음 도식은 부트 CPU의 관계를 요약한다. 전체 커널 초기화 순서는 [[운영체제 기본/x86-64 Linux의 부팅/커널 초기화|커널 초기화]]에서 이어진다.<ref name="gdt-main">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/init/main.c?h=v6.12 Linux v6.12, init/main.c], start_kernel().</ref><ref name="gdt-traps">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/traps.c?h=v6.12 Linux v6.12, arch/x86/kernel/traps.c], trap_init().</ref> | 이 순서 이후 <code>trap_init()</code>이 CPU entry area와 정상 운영용 TSS를 준비한다. 다음 도식은 부트 CPU의 관계를 요약한다. 전체 커널 초기화 순서는 [[운영체제 기본/x86-64 Linux의 BIOS 부팅/커널 초기화|커널 초기화]]에서 이어진다.<ref name="gdt-main">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/init/main.c?h=v6.12 Linux v6.12, init/main.c], start_kernel().</ref><ref name="gdt-traps">[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/traps.c?h=v6.12 Linux v6.12, arch/x86/kernel/traps.c], trap_init().</ref> | ||
<pre> | <pre> | ||