Where are the files located? Whatโs in memory?
Refer to http://duartes.org/gustavo/blog/post/how-computers-boot-up or Appendix A of โUnderstanding Linux Kernelโ book.
/root/linux-2.6.25.10
) and do$ make bzImage
arch/x86/boot/bzImage
$ cp arch/x86/boot/bzImage /boot/bzImage
$ reboot
/boot/grub/grub.conf
.............
title=Gentoo Linux
root (hd0,0)
kernel /kernel-genkernel-x86-2.6.23-gentoo-r8 root= ............
initrd ..............
title=My Linux
root (hd0,0)
kernel /boot/bzImage root=..........
initrd .......
/kernel-genkernel-x86-2.6.23-gentoo-r8
/boot/bzImage
./boot/bzImage
as the operating system.$ cp arch/x86/boot/bzImage /boot/bzImage
$ reboot
BIOS๋ ๋ฉ๋ชจ๋ฆฌ 0xFFFFFFF0
์ ์์นํ๋ค.
GRUB๋ boot disk์ ์ฒซ๋ฒ์งธ sector์ ์กด์ฌํ๋ค.
/boot/grub/grub.conf
์์ ์ฐพ๋๋ค./kernel-genkernel-x86-2.6.23-gentoo-r8
์ ์์ผ๋ฉฐ/boot/bzImage
์ ์๋ค.after
printk(linux_banner);
Add
printk("hello from me\n");
in start_kernel()
. Go to the Linux top directory and compile the kernel and replace the boot image. Reboot with this new kernel, and run dmesg to see if the kernel is printing โhello from meโ.
$ cd linux-2.6.25.10
$ cd init
$ vi main.c
....... modify start_kernel()
$ cd .. -- go back to the Linux top directory
$ make bzImage -- recompile the kernel
$ cp arch/x86/boot/bzImage /boot/bzImage
-- copy the new kernel image to boot location
-- answer "y"
$ reboot -- reboot the system with this new kernel and select "My Linux"
......
(select "My Linux")
$ dmesg > x
$ vi x -- now check if we can see our new message
์ฌ์ง๊ณผ ๊ฐ์ด start_kernel()
ํจ์ ๋ด์์ printk(linux_banner);
๋ค์ ์ค์ printk("HELLO FROM ME!!!\n");
๋ฅผ ์ถ๊ฐํด์ฃผ์๋ค.
๊ทธ ๋ค์ make bzImage
๋ช
๋ น์ด๋ก kernel์ recompile ํด์ฃผ์๋ค.
reboot
ํ, dmesg > x
๋ฅผ ํตํด ๋ถํ
๋ฉ์์ง์ ๋๋ฒ์งธ ์ค์ ํ์ธํด๋ณด๋ฉด ์ถ๊ฐํ โHELLO FROM ME!!!โ๋ฅผ ํ์ธํ ์ ์์๋ค.
start_kernel()
calls trap_init()
, and there are many trap_init()
functions defined in the kernel code. Make an intelligent guess about which trap_init()
would be called and insert some printk()
in the beginning of this trap_init()
to see if it is really called by the kernel. Use grep
in the top directory of the linux source tree to find out the locations of trap_init()
:$ grep -nr "trap_init" * | more
๋ฆฌ๋
์ค์ ํ ๋๋ ํ ๋ฆฌ์์ grep
๋ช
๋ น์ด๋ก โtrap_init
โ ํจ์๋ฅผ ์ฐพ์ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
์ฌ๋ฌ ํ์ผ์ด trap_init()
ํจ์๋ฅผ ๊ฐ๊ณ ์์ง๋ง, kernel์ ์ถ๋ ฅ(printk
)๋๋๋ก ์์ ํ๋ ค๋ฉด, ํ์ฌ ๋ฆฌ๋
์ค์ ์ํคํ
์ฒ๊ฐ x86 32๋นํธ์ด๊ธฐ ๋๋ฌธ์ arch/x86/kernel/
๋๋ ํ ๋ฆฌ์ traps_32.c
ํ์ผ์ ์์ ํด์ผ ํ๋ค.
vi
๋ช
๋ น์ด๋ฅผ ํตํด printk("trap_init function is called by the kernel!!!\n");
๋ผ๋ ๊ตฌ๋ฌธ์ trap_init()
ํจ์์ ์ถ๊ฐํด์ฃผ์๋ค.
$ make bzImage
$ cp arch/x86/boot/bzImage /boot/bzImage
์ ๋ช
๋ น์ด๋ค๋ก ์์ ์ฌํญ์ ์ปดํ์ผ ํด์ฃผ๊ณ , reboot
ํ์๋ค.
$ vi dmesg > x
$ vi x
๋ถํ
๋ฉ์ธ์ง๋ฅผ ํ์ธํด๋ณด๋ฉด 63๋ฒ์งธ ์ค์์๋ถํฐ trap_init
์ด ํธ์ถ๋๋ ๊ฒ์ ์ ์ ์๋ค.
init_IRQ()
and insert some printk()
in the beginning of init_IRQ()
to confirm (actually you insert it in native_init_IRQ
). init_timers()
and time_init()
.$ grep -nr "native_init_IRQ(void)" * | more
๋ฆฌ๋
์ค์ ํ ๋๋ ํ ๋ฆฌ์์ grep
๋ช
๋ น์ด๋ก โinit_IRQ
โ ํจ์๋ฅผ ์ฐพ์ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
์ฌ๋ฌ ํ์ผ์ด native_init_IRQ(void)
ํจ์๋ฅผ ๊ฐ๊ณ ์์ง๋ง, kernel์ ์ถ๋ ฅ(printk
)๋๋๋ก ์์ ํ๋ ค๋ฉด, ํ์ฌ ๋ฆฌ๋
์ค์ ์ํคํ
์ฒ๊ฐ x86 32๋นํธ์ด๊ธฐ ๋๋ฌธ์ arch/x86/kernel/
๋๋ ํ ๋ฆฌ์ i8259_32.c
ํ์ผ์ ์์ ํด์ผ ํ๋ค.
vi
๋ช
๋ น์ด๋ฅผ ํตํด printk("init_IRQ function is called by the kernel!!!\n");
๋ผ๋ ๊ตฌ๋ฌธ์ native_init_IRQ(void)
ํจ์์ ์ถ๊ฐํด์ฃผ์๋ค.
๋ํ, ๋ฆฌ๋
์ค์ ํ ๋๋ ํ ๋ฆฌ์์ grep
๋ช
๋ น์ด๋ก โinit_timers
โ ํจ์์ โtime_init
โ ํจ์๋ฅผ ์ฐพ์ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
$ grep -nr "init_timers(void)" *
$ grep -nr "__init time_init(void)" *
๋ง์ฐฌ๊ฐ์ง๋ก ์ฌ๋ฌ ํ์ผ๋ค ์ค, kernel
ํด๋ ํ์์ ์๋ ํ์ผ์ธ kernel/timer.c
์ arch/x86/kernel/time_32.c
๋ฅผ ์์ ํด์ฃผ์๋ค.
$ vi kernel/timer.c
$ vi arch/x86/kernel/time_32.c
vi
๋ช
๋ น์ด๋ฅผ ํตํด printk("init_timers function is called by the kernel!!!\n");
์
printk("time_init function is called by the kernel!!!\n");
๋ผ๋ ๊ตฌ๋ฌธ์
๊ฐ๊ฐ init_timers(void)
ํจ์์ time_init(void)
ํจ์์ ์ถ๊ฐํด์ฃผ์๋ค.
$ make bzImage
$ cp arch/x86/boot/bzImage /boot/bzImage
์ ๋ช
๋ น์ด๋ค๋ก ์์ ์ฌํญ์ ์ปดํ์ผ ํด์ฃผ๊ณ , reboot
ํ์๋ค.
$ vi dmesg > x
$ vi x
๋ถํ
๋ฉ์ธ์ง๋ฅผ ํ์ธํด๋ณด๋ฉด init_IRQ
, init_timers
, time_init
ํจ์๊ฐ ์์๋๋ก ํธ์ถ๋๋ฉฐ, ์ถ๊ฐํ 3์ข
๋ฅ์ ๋ฌธ๊ตฌ๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ์ ์ ์๋ค.
/boot/grub/grub.conf
so that GRUB displays another Linux selection, My Linux2. Set the location of the kernel for this linux as /boot/bzImage2. Prepare two versions of My Linux such that when you select โMy Linuxโ the kernel will display โhello from My Linuxโ, and when you select โMy Linux2โ, it displays โhello from My Linux2โ.$ cd /boot/grub
$ vi grub.conf
์์ ๊ฐ์ ๋ช
๋ น์ด๋ก /boot/grub/grub.conf
ํ์ผ์ ์์ ํ์๋ค.
โtitle=My Linuxโ๊ฐ ์๋ ์ค์ ์ปค์๋ฅผ ๋๊ณ , 4์ค์ copy ํ๊ธฐ ์ํด 4yy
๋ช
๋ น์ด๋ก ๋ณต์ฌ ํ, p
๋ช
๋ น์ด๋ก ๋ถ์ฌ๋ฃ์๋ค.
๋ถ์ฌ๋ฃ์ ํ
์คํธ ์ค title=My Linux
์ title=My Linux2
๋ก, kernel /boot/bzImage
์ kernel /boot/bzImage2
๋ก ๋ณ๊ฒฝํ์๋ค.
๊ทธ ๋ค์
$ vi init/main.c
start_kernel()
ํจ์๋ก ๊ฐ์ Linux_banner ์์ โhello from My Linuxโ๊ฐ ์ถ๋ ฅ๋๋๋ก ์ ์ฅํ์๋ค.
$ make bzImage
$ cp arch/x86/boot/bzImage /boot/bzImage
cp: overwrite '/boot/bzImage'? y
๋ก โMy Linuxโ kernel์ ์ปดํ์ผํ์๋ค.
์ดํ โMy Linuxโ kernel๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก โMy Linux2โ kernel์ ์์ ํ์๊ณ , ์ปดํ์ผํ์๋ค.
$ vi init/main.c # "start_kernel()" ํจ์์์
# "hello from My Linux2"๋ฅผ ์ถ๋ ฅํ๋๋ก ์์
$ make bzImage
$ cp arch/x86/boot/bzImage /boot/bzImage2
$ reboot
๋ถํ ํ๋ฉด์์ โMy Linux2โ๊ฐ ์ถ๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฐ์ โMy Linuxโ๋ก ๋จผ์ ๋ถํ ํ์ฌ ๋ถํ ๋ฉ์ธ์ง๋ฅผ ํ์ธํด๋ณธ๋ค.
$ dmesg > x
$ vi x
start_kernel
ํจ์์ ์ถ๊ฐํ ๋ฉ์ธ์ง๊ฐ ์ ์ ์ถ๋ ฅ๋๋ค.
โMy Linux2โ๋ก ์ฌ๋ถํ ํ์ฌ ๋ถํ ๋ฉ์ธ์ง๋ฅผ ํ์ธํด๋ดค์ ๋๋, ์ถ๊ฐํ โhello from My Linux2โ๋ผ๋ ๋ฉ์ธ์ง๊ฐ ์ ์ ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
main.c
์์ ๋ถํ
์ ๊ฐ์ฅ ๋จผ์ ์คํ๋๋ start_kernel
์ ๊ฐ์ฅ ๋ง์ง๋ง ๋ถ๋ถ์ ๋ณด๋ฉด rest_init();
์ด ์๋ค.
rest_init()
ํจ์ ๋ํ init/main.c
์ ์ ์๋์ด ์๋ค.
rest_init()
ํจ์ ์์์๋ cpu_idle();
์ด ์ ์ผ ๋ง์ง๋ง์ผ๋ก ์คํ๋๋ค.
$ grep -nr "cpu_idle" * | more
์ ์คํ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด
cpu_idle
ํจ์๋ arch/x86/kernel/process_32.c
์ ์๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
ํจ์ ๋ด์ฉ์ ํ์ธํด๋ณด๋, cpu๋ ์ฌ์ฉ์๋ก๋ถํฐ id๋ฅผ ์
๋ ฅ๋ฐ๊ธฐ ์ ๊น์ง while
๋ฌธ์ ํตํด์ ๋ฌดํ๋ฃจํ๋ฅผ ๋๊ฒ
๋๋ค.
์ฆ, cpu๋ login:
๋ฅผ ํ๋ฉด์ ์ถ๋ ฅํ ํ ๋ฉ์ถฐ์๋ ๊ฒ์ด ์๋๋ผ cpu_idle
์ ๋ฌดํ๋ฃจํ์์ ์ฌ์ฉ์์ ์
๋ ฅ ์ ๊น์ง ๊ณ์ ๋๊ธฐ ์ค์ธ ๊ฒ์ด๋ค.