GeekOS源代码学习(0)

时间:2022-12-09 16:31:06



我使用的是geekos-0.3.0,从 这里下载。
doc目录下的hacking.pdf有详细的运行说明,只有40页,英文也很简单,稍微仔细的看一下。


我们开始
建立project0
$startProject project0 ./geekos-0.3.0/src
这样在当下目录下生成了project0目录
$cd ./project0/build
$make depend
$make
编译文件,最后生成了fd.img软盘映像文件。
$file fd.img
fd.img: Linux kernel
好,先来试试看再说。
使用在我的上篇文章《sagalinux学习之/boot目录》中的bochsrc,只要改一下软盘名字就好了。
先来看看效果!!

GeekOS源代码学习(0)


哈哈,看到了吧。

带蓝色背景的字是你需要完成的任务。

pdf上的共有7个project,每一个都会让你完成一个任务,最终任务完成之后,就是一个真正的小型的类unix OS了。。。激动。。。
project0要求你完成键盘输入的响应,其实源代码函数都已经写好了,只要你调用一下函数就行了。


不管project0,我先read the f**king source code...
来看一下Makefile,对整体有个结构上的理解
$vi ./build/Makefile

Makefile 

# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
# $Revision: 1.45 $

# This is free software. You are permitted to use,
# redistribute, and modify it as specified in the file "COPYING".

# Required software to build GeekOS:
# - GNU Make (http://www.gnu.org/software/make)
# - gcc 2.95.2 generating code for target (i386/ELF) and host platforms
# - nasm (http://nasm.sourceforge.net)
# - Perl5, AWK (any version), egrep
#
# Cygwin (http://cygwin.com) may be used to build GeekOS.
# Make sure that gcc, binutils, nasm, and perl are installed.

# NOTES:
# - This makefile has been written carefully to work correctly
# with the -j (parallel make) option. I regularly use "make -j 2"
# to speed the build process on 2 processor systems.

PROJECT_ROOT := ..
VPATH := $(PROJECT_ROOT)/src

# Figure out if we're compiling with cygwin, http://cygwin.com
SYSTEM_NAME := $(shell uname -s)
ifeq ($(findstring CYGWIN,$(SYSTEM_NAME)),CYGWIN)
SYM_PFX := _
EXTRA_C_OPTS := -DNEED_UNDERSCORE -DGNU_WIN32
EXTRA_NASM_OPTS := -DNEED_UNDERSCORE
NON_ELF_SYSTEM := yes
EXTRA_CC_USER_OPTS := -Dmain=geekos_main
endif

# ----------------------------------------------------------------------
# Configuration -
# Various options specifying how GeekOS should be built,
# what source files to build, which user programs to build,
# etc. This is generally the only section of the makefile
# that will need to be modified.
# ----------------------------------------------------------------------

# List of targets to build by default.
# These targets encompass everything needed to boot
# and run GeekOS.
ALL_TARGETS := fd.img


# Kernel source files
KERNEL_C_SRCS := idt.c int.c trap.c irq.c io.c \
keyboard.c screen.c timer.c \
mem.c crc32.c \
gdt.c tss.c segment.c \
bget.c malloc.c \
synch.c kthread.c \
main.c

# Kernel object files built from C source files,将KERNEL_C_SRCS中的xxx.c文件替换成xxx.o并移至当前的geekos目录下
KERNEL_C_OBJS := $(KERNEL_C_SRCS:%.c=geekos/%.o)

# Kernel assembly files
KERNEL_ASM_SRCS := lowlevel.asm


# Kernel object files build from assembler source files
KERNEL_ASM_OBJS := \
$(KERNEL_ASM_SRCS:%.asm=geekos/%.o)


# All kernel object files,所有的内核目标文件
KERNEL_OBJS := $(KERNEL_C_OBJS) \
$(KERNEL_ASM_OBJS)

# Common library source files.库文件
# This library is linked into both the kernel and user programs.
# It provides string functions and generic printf()-style
# formatted output.
COMMON_C_SRCS := fmtout.c string.c memmove.c

# Common library object files.
COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)


# Base address of kernel,内核在内存中的基址
KERNEL_BASE_ADDR := 0x00010000

# Kernel entry point function,设置内核入口
KERNEL_ENTRY = $(SYM_PFX)Main


# ----------------------------------------------------------------------
# Tools -
# This section defines programs that are used to build GeekOS.
# ----------------------------------------------------------------------

# Uncomment if cross compiling
#TARGET_CC_PREFIX := i386-elf-

# Target C compiler. gcc 2.95.2 or later should work.
TARGET_CC := $(TARGET_CC_PREFIX)gcc

# Host C compiler. This is used to compile programs to execute on
# the host platform, not the target (x86) platform. On x86/ELF
# systems, such as Linux and FreeBSD, it can generally be the same
# as the target C compiler.
HOST_CC := gcc

# Target linker. GNU ld is probably to only one that will work.各种工具
TARGET_LD := $(TARGET_CC_PREFIX)ld

# Target archiver
TARGET_AR := $(TARGET_CC_PREFIX)ar

# Target ranlib
TARGET_RANLIB := $(TARGET_CC_PREFIX)ranlib

# Target nm
TARGET_NM := $(TARGET_CC_PREFIX)nm

# Target objcopy
TARGET_OBJCOPY := $(TARGET_CC_PREFIX)objcopy

# Nasm (http://nasm.sourceforge.net)
NASM := nasm

# Tool to build PFAT filesystem images.
BUILDFAT := tools/builtFat.exe

# Perl5 or later
PERL := perl

# Pad a file so its size is a multiple of some unit (i.e., sector size),以0填充文件使之达到要求的大小
PAD := $(PERL) $(PROJECT_ROOT)/scripts/pad

# Create a file filled with zeroes.,创建一个内容为‘0’的文件
ZEROFILE := $(PERL) $(PROJECT_ROOT)/scripts/zerofile

# Calculate size of file in sectors,以扇区计算文件
NUMSECS := $(PERL) $(PROJECT_ROOT)/scripts/numsecs


# ----------------------------------------------------------------------
# Definitions -
# Options passed to the tools.
# ----------------------------------------------------------------------

# Flags used for all C source files,消除编译器对栈的检查
GENERAL_OPTS := -O -Wall -fno-stack-protector $(EXTRA_C_OPTS)
CC_GENERAL_OPTS := $(GENERAL_OPTS)

# Flags used for kernel C source files
CC_KERNEL_OPTS := -g -DGEEKOS -I$(PROJECT_ROOT)/include

# Flags user for kernel assembly files
NASM_KERNEL_OPTS := -I$(PROJECT_ROOT)/src/geekos/ -f elf $(EXTRA_NASM_OPTS)

# Flags used for common library and libc source files
CC_USER_OPTS := -I$(PROJECT_ROOT)/include -I$(PROJECT_ROOT)/include/libc \
$(EXTRA_CC_USER_OPTS)

# Flags passed to objcopy program (strip unnecessary sections from kernel.exe)
OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment

# ----------------------------------------------------------------------
# Rules -
# Describes how to compile the source files.
# ----------------------------------------------------------------------

# Compilation of kernel C source files
#geekos/下的.o目标文件依赖.c源文件
geekos/%.o : geekos/%.c
$(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o


# Compilation of kernel assembly source files
geekos/%.o : geekos/%.asm
$(NASM) $(NASM_KERNEL_OPTS) $< -o geekos/$*.o

geekos/%.o : geekos/%.S
$(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o

# Compilation of common library C source files
common/%.o : common/%.c
$(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_USER_OPTS) $< -o common/$*.o

# ----------------------------------------------------------------------
# Targets -
# Specifies files to be built
# ----------------------------------------------------------------------

# Default target - see definition of ALL_TARGETS in Configuration section
all : $(ALL_TARGETS)

# Standard floppy image - just boots the kernel
fd.img : geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin
cat geekos/fd_boot.bin geekos/setup.bin geekos/kernel.bin > $@

# Floppy boot sector (first stage boot loader).这里动态的计算setup.bin和kernel.bin占软盘扇区大小并插入到boot.asm中的变量中,以将其载入到内存中
geekos/fd_boot.bin : geekos/setup.bin geekos/kernel.bin $(PROJECT_ROOT)/src/geekos/fd_boot.asm
$(NASM) -f bin \
-I$(PROJECT_ROOT)/src/geekos/ \
-DNUM_SETUP_SECTORS=`$(NUMSECS) geekos/setup.bin` \ #NUM_SETUP_SECTORS是fd_boot.asm中的变量名,在这里赋值
-DNUM_KERN_SECTORS=`$(NUMSECS) geekos/kernel.bin` \
$(PROJECT_ROOT)/src/geekos/fd_boot.asm \
-o $@

# Setup program (second stage boot loader).
geekos/setup.bin : geekos/kernel.exe $(PROJECT_ROOT)/src/geekos/setup.asm
$(NASM) -f bin \
-I$(PROJECT_ROOT)/src/geekos/ \
-DENTRY_POINT=0x`egrep 'Main$$' geekos/kernel.syms |awk '{print $$1}'` \ #ENTRY_POINT为内核的代码入口,从setup代码跳入
$(PROJECT_ROOT)/src/geekos/setup.asm \
-o $@
$(PAD) $@ 512

# Loadable (flat) kernel image.
geekos/kernel.bin : geekos/kernel.exe
$(TARGET_OBJCOPY) $(OBJCOPY_FLAGS) -S -O binary geekos/kernel.exe geekos/kernel.bin
$(PAD) $@ 512

# The kernel executable and symbol map.
geekos/kernel.exe : $(KERNEL_OBJS) $(COMMON_C_OBJS)
$(TARGET_LD) -o geekos/kernel.exe -Ttext $(KERNEL_BASE_ADDR) -e $(KERNEL_ENTRY) \
$(KERNEL_OBJS) $(COMMON_C_OBJS)
$(TARGET_NM) geekos/kernel.exe > geekos/kernel.syms

# Clean build directories of generated files
clean :
for d in geekos common libc user tools; do \
(cd $$d && rm -f *); \
done

# Build header file dependencies, so source files are recompiled when
# header files they depend on are modified.
depend : $(GENERATED_LIBC_SRCS)
$(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) \
$(KERNEL_C_SRCS:%.c=$(PROJECT_ROOT)/src/geekos/%.c) \
| $(PERL) -n -e 's,^(\S),geekos/$$1,;print' \
> depend.mak
$(TARGET_CC) -M $(CC_GENERAL_OPTS) $(CC_USER_OPTS) \
$(COMMON_C_SRCS:%.c=$(PROJECT_ROOT)/src/common/%.c) \
| $(PERL) -n -e 's,^(\S),common/$$1,;print' \
>> depend.mak

# By default, there are no header file dependencies.
depend.mak :
touch $@

include depend.mak


可以看到和sagalinux类似,生成了fd_boot.bin,setup.bin,kernel.bin文件,并最终通过cat命令生成软盘映像。

我们还是从系统启动开始看起,下一篇来分析./src/geekos/fd_boot.asm和setup.asm源代码。