- main.c : beginning of linux
- fork.c, exit.c, sched.c : process creation, exit, scheduling
- arch/x86 : cpu-dependent code for intel x86 cpu
- arch/x86/boot : boot-related code
- arch/x86/kernel: low-level intel cpu code for initialization, interrupt handling, etc
- entry_32.S : code for interrupt entry point
- head_32.S : code for system initialization
- i8259_32.c : code for interrupt controller
- irq_32.c : code for IRQ
- process_32.c : code for process control
- time_32.c : code for timer
- traps_32.c : code for exception handling
- signal_32.c : code for signal handling
- open.c, read_write.c, file.c, ... : fs system call handling
- inode.c : inode handling
- fs/ext2 : ext2 file system code
- fs/ntfs : windows NT file system code
- inclde/asm-x86 : include files for intel cpu specific code
-
Linux is the first program that runs when the system boots.
-
Linux begins at init/main.c/start_kernel().
-
Linux uses
printk
(not "printf") to display messages. -
All booting messages are displayed by Linux with
printk
and you can find the corresponding Linux code that prints each boot message. -
All boot messages are stored in the kernel buffer and you can display this buffer with
dmesg
command. -
Find Linux code that prints the first boot message.
https://www.virtualbox.org/wiki/Downloads
1.2) Run VirtualBox, and click File>Import and go to the gentoo directory. Select Gentoo2.ovf. Uncheck USB controller. Select Import. This will install Gentoo Linux on your virtual box.
If you have an error, run VirutalBox as administrator and try again. For USB error, simply disable usb controller in "Setting" tab. For Hyper-V error (Raw-mode is unavailable), turn off Hyper-V feature in control panel>program and feature>window feature. Select My Linux. Login as root and hit Enter for the password prompt. If VirtualBox still cannot open the session, you need to look at the log file (right click on Gentoo VM and select โlog fileโ) and see what is the error and fix it. (In some cases, you may need to download and install virtualbox extension package.)
2. Go to linux-2.6.25.10 directory and find all the files referred in Section 1 such as main.c, fork.c, entry_32.S, etc.
main.c๋ init ํด๋์ ์์ผ๋ฉฐ ๋ฆฌ๋ ์ค์ ์์์ ์ด๋ค. start_kernel() ํจ์๋ main.c์ ์์นํ๋ค.
fork.c๋ kernel ํด๋์ ์์ผ๋ฉฐ ์ด ํด๋์๋ ํ๋ก์ธ์ค์ ๊ด๋ จ๋ ํ์ผ์ด ์๋ค.
find / -name entry_32.S -type f
find
๋ช
๋ น์ด๋ฅผ ํตํด entry_32.S์ ์์น๋ฅผ ์ฐพ์๋ณด๋ฉด
entry_32.S๋ "arch/x86/kernel"์ "arch/powerpc/kernel"์ ์๋ค. ์ด ์ค "x86" ํด๋์๋ ์ํคํ
์ฒ๋ง๋ค ๋ค๋ฅด๊ฒ ๋์ํ๋ ํจ์๋ค์ด ๋ด๊ฒจ์์ผ๋ฉฐ "x86"์ ์ธํ
์ 32๋นํธ ์ํคํ
์ฒ๋ฅผ ์๋ฏธํ๋ค.
To find a string "start_kernel", go to the linux top directory (linux-2.6.25.10) and do
$ grep -nr "start_kernel" * | more
Use "space"
to move down the screen, q
to exit
Once you found the file that has "start_kernel", use vi
to read the file.
In vi, type /start_kernel
to search for the first instance of "start_kernel".
For the next string, simply type "/". Repeat "/" until you find the start_kernel()
function.
Use "j" to mode down the cursor, "k" to move up, "^f" to move one screen down, "^b" to move
up one screen up.
4. start_kernel()
is the first C function run by Linux.
Predict what will be the first message appearing on the screen by analyzing start_kernel()
.
Note that printk()
(not printf
) is the function to print something in the kernel.
Confirm your prediction with dmesg > x
and vi x
.
The kernel remembers the booting message in the system buffer and dmesg displays the content of this buffer to the screen.
dmesg > x
will send the booting message to file x
.
With vi x
you can look at the file x
.
start_kernel()
ํจ์์ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ๋ค.
์ด ์ค ๊ฐ์ฅ ๋จผ์ printk
๊ฐ ์ฌ์ฉ๋ ๋ถ๋ถ์ ์๋์ ๊ฐ๋ค.
printk(KERNEL_NOTICE);
printk(linux_banner);
์ฒซ ๋ฒ์งธ ์ถ๋ ฅ์ ์ ๋ ํจ์ ํธ์ถ๋ก KERN_NOTICE
๋ ์ถ๋ ฅ์ ๋ก๊ทธ ๋ ๋ฒจ์ ์ค์ ํ๋ ๊ธฐํธ๋ก ๋ค์ ์ถ๋ ฅ์ด ์ ์์ ์ธ ์ ๋ณด์ ํด๋นํ๋ ๋ก๊ทธ์์ ๋ํ๋ธ๋ค. ๊ทธ๋ ๋ค๋ฉด linux_banner
๊ฐ ์ง์ง ์ถ๋ ฅ์ธ๋ฐ ํด๋น ๊ฐ์ด ์ ์๋ init/version.c
์ผ๋ก ๊ฐ๋ฉด ์๋์ ๊ฐ์ด ๋ฆฌ๋
์ค์ ๋ฒ์ ๊ณผ ์ปดํ์ผ ํ๊ฒฝ์ ์ถ๋ ฅํ๋ ๋ฌธ์์ด์ด ๊ตฌ์ฑ๋์ด ์๋ค.
init/version.c:
/* FIXED STRINGS! Don't touch! */
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
๋ฐ๋ผ์ ๋ฆฌ๋ ์ค๊ฐ ๋ถํ ๋๋ฉด ๋ฆฌ๋ ์ค์ ๋ฒ์ ๊ณผ ์ปดํ์ผ ํ๊ฒฝ์ด ๊ฐ์ฅ ๋จผ์ ์ถ๋ ฅ๋ ๊ฒ์ด๋ค.
dmesg > x
๋ฅผ ํตํด ๋ถํ
๋ฉ์ธ์ง๋ฅผ ํ์ธํด๋ณธ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
๋ฆฌ๋ ์ค ๋ฒ์ ๊ณผ GCC ์ ๋ณด๊ฐ ๊ฐ์ฅ ๋จผ์ ์ถ๋ ฅ๋๋ค.
5. Find the location of the following functions called in start_kernel() and briefly explain your guessing about what each function is doing (but do not copy the whole code).
$ grep -nr "trap_init" * | more
linux-2.6.25.10/arch/x86/
์์ ์ ๋ช
๋ น์ด๋ก "trap_init"์ ์ฐพ์๋ณด์๋ค.
arch/x86/kernel/traps_64.c:1127
์ arch/x86/kernel/traps_32.c:1140
์์ void __init trap_init(void)
๊ฐ ์ฌ์ฉ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
$ vi kernel/traps_32.c
์ ๋ช
๋ น์ด๋ฅผ ํตํด traps_32.c
ํ์ผ์ trap_init(void)
ํจ์๋ฅผ ์ดํด๋ณด์๋ค.
set_trap_gate(0,÷_error);
set_intr_gate(1,&debug);
set_intr_gate(2,&nmi);
set_system_intr_gate(3, &int3); /* int3/4 can be called from all */
set_system_gate(4,&overflow);
set_trap_gate(5,&bounds);
set_trap_gate(6,&invalid_op);
set_trap_gate(7,&device_not_available);
set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS);
set_trap_gate(9,&coprocessor_segment_overrun);
set_trap_gate(10,&invalid_TSS);
set_trap_gate(11,&segment_not_present);
set_trap_gate(12,&stack_segment);
set_trap_gate(13,&general_protection);
set_intr_gate(14,&page_fault);
set_trap_gate(15,&spurious_interrupt_bug);
set_trap_gate(16,&coprocessor_error);
set_trap_gate(17,&alignment_check);
trap_init()
ํจ์์๋ ์์ ๊ฐ์ด set ํจ์๊ฐ ๋์ด๋์ด ์๋ค. ์ด๊ฒ์ผ๋ก ์ ์ถํด๋ณธ๋ค๋ฉด, ์์คํ
์ฝ์ ์ํ ์
ํ
์ด ์ด๋ฃจ์ด์ง๋ ๊ฒ ๊ฐ๋ค.
$ grep -nr "init_IRQ" * | more
linux-2.6.25.10/arch/x86/
์์ ์ ๋ช
๋ น์ด๋ก "init_IRQ"์ ์ฐพ์๋ณด์๋ค.
arch/x86/kernel/paravirt.c:167
์์ void init_IRQ(void)
๊ฐ ์ฌ์ฉ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
$ vi kernel/paravirt.c
$ vi kernel/i8259_64.c
i8259_64.c
์ native_init_IRQ(void)
ํจ์์
...
set_intr_gate(vector, interrupt[i]);
...
๋ฅผ ๋ณด๋ฉด, interrupt gate๋ฅผ ์ด๊ธฐํํ๋ ๊ฒ์ผ๋ก ์ ์ถํด๋ณผ ์ ์๋ค.
IRQ๋ Interrupt ReQuest์ ์ฝ์๋ก, ์ธํฐ๋ฝํธ ์ ํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ์ ์ฐ์ด๋ ์ปดํจํฐ ๋ฒ์ค ๋ผ์ธ์ ์ธํฐ๋ฝํธ ๋์์ ๋งํ๋ค.
init_IRQ()
๋ ์ปค๋ interrupt subsystem์ ํ๋์จ์ด ์ผ๋ถ๋ฅผ ์ด๊ธฐํํ๋ ๊ฒ์ผ๋ก ์ ์ถํ ์ ์๋ค.
$ grep -nr "sched_init(void)" *
linux-2.6.25.10/
์์ ์ ๋ช
๋ น์ด๋ก "sched_init"์ ์ฐพ์๋ณด์๋ค.
kernel/sched.c:7261
์์ void __init sched_init(void)
๊ฐ ์ฌ์ฉ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
$ vi kernel/sched.c
sched_init(void)
๋ init task๊ฐ ์ฌ์ฉํ๋ CPU ๋ฒํธ๋ฅผ ํ ๋นํ๊ณ PID HASH TABLE์ ์ด๊ธฐํํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ปค๋์ ๋ด๋ถ ํ์ด๋จธ๊ฐ ์ฌ์ฉํ๋ ๋ฒกํฐ ๋ฐ bottom-half handler๋ฅผ ์ด๊ธฐํํ๋ค.
$ grep -nr "time_init(void)" *
linux-2.6.25.10/arch/x86/
์์ ์ ๋ช
๋ น์ด๋ก "time_init"์ ์ฐพ์๋ณด์๋ค.
arch/x86/kernel/time_32.c:135
์ arch/x86/kernel/time_64.c:117
์์ void __init time_init(void)
๊ฐ ์ฌ์ฉ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
$ vi kernel/time_32.c
$ grep -nr "tsc_init" *
$ vi kernel/tsc_32.c
CMOS์์ ์๊ฐ์ ์ฝ๊ณ CPU์ ์๋๋ฅผ ์ป์ด๋ด๋ ๊ฒ์ผ๋ก ์ถ์ธกํ ์ ์๋ค.
$ grep -nr "__init console_init(void)" *
linux-2.6.25.10/
์์ ์ ๋ช
๋ น์ด๋ก "console_init"์ ์ฐพ์๋ณด์๋ค.
drivers/char/tty_io.c:4037
์ void __init console_init(void)
ํจ์๊ฐ ์ฌ์ฉ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
$ vi drivers/char/tty_io.c
์ปค๋์ ์ง๋ ฌ ์ฝ์ ๋๋ฐ์ด์ค๊ฐ ์ฌ์ฉํ๋๋ก ๊ตฌ์ฑ๋ ๊ฒฝ์ฐ ์ด๊ธฐํ๋ฅผ ์ํํ๋ค.
$ grep -nr "mem_init" *
linux-2.6.25.10/
์์ ์ ๋ช
๋ น์ด๋ก "mem_init"์ ์ฐพ์๋ณด์๋ค.
arch/x86/mm/init_64.c:511
์ arch/x86/mm/init_32.c:569
์์ void __init mem_init(void)
๊ฐ ์ฌ์ฉ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
$ vi mm/init_32.c
์ ๋ช
๋ น์ด๋ฅผ ํตํด init_32.c
ํ์ผ์ void __init mem_init(void)
ํจ์๋ฅผ ์ดํด๋ณด์๋ค.
์ปค๋์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์๋ธ ์์คํ ์ ์ด๊ธฐํ๋ฅผ ๋ด๋นํ๋ ํจ์๋ก ์์ธกํ ์ ์๋ค.
$ grep -nr "rest_init" *
linux-2.6.25.10/
์์ ์ ๋ช
๋ น์ด๋ก "rest_init"์ ์ฐพ์๋ณด์๋ค.
rest_init()
ํจ์๋ linux-2.6.25.10/init/main.c
์ ์์นํ ๊ฒ์ ํ์ธํ ์ ์๋ค.
$ vi init/main.c
์ ๋ช
๋ น์ด๋ฅผ ํตํด main.c
ํ์ผ์ rest_init(void)
ํจ์๋ฅผ ์ดํด๋ณด์๋ค.
์ด๊ธฐํ ๊ธฐ๋ฅ์ ์ฌ์ฉ๋๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ ํ ์ปค๋ thread๋ก init()
์ ์์ํ์ฌ ์ปค๋ ๋ถํ
์ ์๋ฃํ๋ค.
printf
printf
๋ ์ ์ ๋ชจ๋์์๋ง ํธ์ถ์ด ๊ฐ๋ฅํ๋ค.printf
ํจ์์ ๊ฒฝ์ฐ ๋ด๋ถ์ ์ผ๋ก ๋ฒํผ์ ์ถ๋ ฅํ ๊ฒ์ ๋ชจ์๋์๋ค๊ฐ ๋ฐฉ์ถ์ํจ๋ค.
printk
printk
๋ OS ๋์ ์ค์ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๋ ์ฉ๋์ด๋ฉฐ ์ปค๋๋ชจ๋์์๋ง ํธ์ถ์ด ๊ฐ๋ฅํ๋ค.printk
๋ ๋ฒํผ์์ด ๋ฐ๋ก ์ถ๋ ฅํ๋ค.- OS์ ํต์ฌ ์ฝ๋์ธ kernel์๋ OS ์ด์ ์ค ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๊ด๋ จ ๋ก๊ทธ๋ฅผ ๊ธฐ๋กํ๋ ๋์ ์ฝ๋ ๋ฑ์ด ํฌํจ๋์ด ์๋ค. ๋ฐ๋ผ์ ์์ฃผ ์งง์ ์๊ฐ๋ ์น๋ช
์ ์ผ ์ ์๊ธฐ์
printf
๋ณด๋ค ๊ฐ๋ณ๊ฒ ๋์ํ๋printk
๋ฅผ ์ด์ฉํ๋ค. - ๋ํ ๋ฉ์์ง ์ถ๋ ฅ ๋ก๊ทธ ๋ ๋ฒจ์ ์ง์ ํ๊ธฐ ์ํด
printk
๋ฅผ ์ด์ฉํ๋ค.