0から作るソフトウェア開発
日々勉強中。。。 |
Follow @Nina_Petipa |
0から作るOS開発 カーネルことはじめ |
/usr/bin
i686-pc-linux-gnu-gcc.exe
i686-pc-linux-gnu-as.exe
i686-pc-linux-gnu-ld.exe
/home/ユーザ名/.bash_profile
コンピューター → Cドライブ → cygwin → home → ユーザ名フォルダの.bash_profile
PATH="${PATH}:/usr/bin"
セクション定義 | |
---|---|
セクション名 | 説明 |
.text |
プログラムのコード(関数)が配置されるセクションとなります 通常プログラムのコードはROMに置きますがパソコンの場合はROMが無いのでメモリに置きます |
.rodata |
プログラムの定数が配置されるセクションとなります C言語でconstで宣言したものはここに配置されます 通常プログラムの定数はROMに置きますがパソコンの場合はROMが無いのでメモリに置きます |
.data |
プログラムの初期値付き変数が配置されるセクションです C言語ではグローバル変数に初期値を定義するとここに配置されます 通常初期値付き変数の初期値はROMに置いておき、カーネル起動直後に このセクションをRAMにコピーする必要があります。パソコンではROMが無いので 最初からコピーされた領域として扱って差し障りありません 携帯電話等の他のシステムのOSを作るときは、.dataのROMセクションと RAMセクションを定義しておき、ROMからRAMにコピーする作業が必要です |
.bss |
プログラムの初期値無し変数が配置されるセクションです C言語ではグローバル変数を宣言(初期値は定義しない)するとここに配置されます このセクションは通常RAMに置きます。通常初期値無し変数は初期化されていませんので、 カーネル起動直後はこのセクションは不定値となっています。 ANSI C規格 に従うため カーネル起動した後に.bssセクションを0で初期化する必要があります |
.vectors |
割り込みベクタが配置されるセクションです CPU依存部分です。通常ROMに配置されます IntelのCPUでは、割り込みベクタはRAMに自由に配置できますので、 パソコンでは特に定義する必要はありません 組み込みシステムでは必要となってきます |
.stack |
スタックが配置されるセクションです 通常RAMに配置されます。スタック領域を自分で管理できる限りは特に 定義する必要はありません。組み込みシステムなどRAM容量が少ない システムでは.stackを定義したりします (組み込みシステムで定義しておくと、.dataや.bssが使用するRAM領域が .stackまであふれてしまったときにリンカエラーがでるのでRAM領域の使用量を管理できます) |
SECTIONS
{
SECTIONS-COMMAND
SECTIONS-COMMAND
...
}
SECTIONS-COMMAND | |
---|---|
コマンド | 説明 |
'Entry'コマンド | プログラムのエントリーポイント(プログラムが一番最初に実行されるアドレス)を指定します |
シンボルの割り当て |
シンボルを定義することができます (変数の宣言みたいなものと考えて頂ければいいと思います) |
アウトプットセクション |
アウトプットするセクションのコマンドを定義します ここに.textなどのセクションを定義していきます |
オーバーレイ | セクション同士の領域を重ねるときにつかいます |
SECTION [ADDRESS] :
{
OUTPUT-SECTION-COMMAND
OUTPUT-SECTION-COMMAND
...
}
.text 0x00100000 :
{
*(.text)
}
SECTIONS
{
. = 0x100000;
.text :
{
_text_start = .;
*(.text)
_text_end = .;
}
.rodata :
{
_rodata_start = .;
*(.rodata)
_rodata_end = .;
}
.data :
{
_data_start = .;
*(.data)
_data_end = .;
}
.bss :
{
_bss_start = .;
*(.bss)
_bss_end = .;
}
}
. = 0x100000;
_bss_start = .;
コンパイルオプション | |
---|---|
オプション | 説明 |
-Wall |
コンパイル時にすべての警告を出してくれます(Warning all) コンパイルした時にWaringが出てきますので、なるべくWarningを消すように すると自分では気付かない静的なバグが取り除けます |
-O |
プログラムを最適化してくれます。-Oの後に数字の1から3を入れ、 最適化のレベルを指定します。一般的には-O2までを指定します |
-I |
インクルードファイル(ヘッダファイル)が有るディレクトリを指定します 自分で作ったヘッダファイルがあるディレクトリを指定しておけば、 コンパイル時にヘッダファイルを読み込んでくれます |
-c |
リンカを起動しないようにするオプションです オブジェクトファイルを作るところまで実行します このオプションは複数のファイルをコンパイルするときに使用すると便利です |
-o | 出力するファイル名を指定します |
リンカオプション | |
---|---|
オプション | 説明 |
-T | 読み込むリンカスクリプトのファイル名を指定します |
-Map | リンケージした後のメモリマップを出力するファイル名を指定します |
-nostdlib |
標準ライブラリをリンクしないようにします カーネルはprintfなどの標準ライブラリの関数を使用することができません (できることはできるのですが、それには多大な労力が必要です) 標準ライブラリとリンクしないようにオプション設定します |
-e |
プログラムが一番最初に実行される関数アドレス(エントリ:entry)を指定します カーネルのメイン関数名を指定します このオプションを指定せずにリンカスクリプトで定義することもできます |
--oformat |
--oformatで指定したファイル形式で実行ファイルを作成します このサイトでは--oformat binaryを指定して実行バイナリのみ出力させます Cygwinをインストールした時の標準GCCでは、このオプションを指定しても 効果が無く、Cygwin用のヘッダを強制的に付加してしまいます それでも、カーネルの実行をすることはできるのですが、ちょっとめんどくさいので、 このサイトではクロスコンパイラを使用することにしています |
-o | 出力するファイル名を指定します |
-r |
リロケータブル(再配置可能な)オブジェクトファイルを出力します このオプションは部分的にリンキングをしたいときに使用します |
i686-pc-linux-gnu-gcc -c -o kernel.o kernel.c -O2 -I../include -Wall
i686-pc-linux-gnu-ld -T linkerscript -Map kernel.map -nostdlib -e _kernel_entry \
--oformat binary -o KImage kernel.o
i686-pc-linux-gnu-gcc -c -o driver.o driver.c -O2 -I../include -Wall
i686-pc-linux-gnu-ld -r -o kernel.o krnl.o driver.o
make
ターゲット:ソース
コマンド
kernle.o:kernel.c
i686-pc-linux-gnu-gcc -c -o kernle.o kernel.c -O2 -I../include -Wall
KImage:kernel.o
i686-pc-linux-gnu-ld -T linkerscript -Map kernel.map -nostdlib -e _kernel_entry \
--oformat binary -o KImage kernel.o
GCC = i686-pc-linux-gnu-gcc
CFLAGS = -O2 -I../include -Wall
LD = i686-pc-linux-gnu-ld
LFLAGS = -T linkerscript -Map kernel.map -nostdlib -e _kernel_entry --oformat binary
AS = i686-pc-linux-gnu-ar
KOBJECT = kernel.o
KSOURCE = kernel.c
KIMAGE = KImage
INCLUDE = ../include
$(KOBJECT):$(KSOURCE)
$(GCC) -c -o $(KOBJECT) $(KSOUrCE) $(CFLAGS)
$(KIMAGE):$(KOBJECTC)
$(LD) $(LFLAGS) -o $(KIMAGE) $(KOBJECT)
#=============================================================================== # TARGETS #===============================================================================
BOOT = boot LOADER = STARTING.IMG LOADERASM = Starting.asm KERNEL = KImage KOBJECTS = kernel/krnl.o driver/driver.o
#=============================================================================== # DEFINES #===============================================================================
HOME_DIR = "$(CURDIR)" CC = i686-pc-linux-gnu-gcc CFLAGS = -fomit-frame-pointer -O2 -I$(HOME_DIR)/include -masm=intel -Wall ASFLAGS = -msyntax=intel -march=i686 --32 LFLAGS = -T linkerscript -Map kernel.map -nostdlib -e _kernel_entry --oformat binary ASM = nasm AS = i686-pc-linux-gnu-as LD = i686-pc-linux-gnu-ld DD = dd CP = cp RM = rm CD = cd MAKE = make IMDISK = /proc/sys/Device/ImDisk0 ADRIVE = /cygdrive/a export HOME_DIR export CC export CFLAGS export LD export ASFLAGS export AS
$(BOOT).img:$(BOOT)/$(BOOT).asm
$(ASM) -o $(BOOT).img $(BOOT)/$(BOOT).asm
$(LOADER):$(BOOT)/$(LOADERASM)
$(ASM) -I$(BOOT) -o $(LOADER) $(BOOT)/$(LOADERASM)
kernel/krnl.o:
($(CD) kernel;$(MAKE))
driver/driver.o:
($(CD) driver;$(MAKE))
$(KERNEL):$(KOBJECTS)
$(LD) $(LFLAGS) -o $(KERNEL) $(KOBJECTS)
make clean
#------------------------------------------------------------------------------- # Clear Objects #-------------------------------------------------------------------------------
.PHONY: clean clean: $(RM) -f $(BOOT).img $(LOADER) $(KERNEL) ($(CD) driver; $(MAKE) clean) ($(CD) kernel; $(MAKE) clean)
#------------------------------------------------------------------------------- # Install Kernel #-------------------------------------------------------------------------------
.PHONY: install install: $(BOOT).img $(LOADER) $(KERNEL) $(ASM) -o $(BOOT).img $(BOOT)/$(BOOT).asm ($(CD) kernel;$(MAKE)) ($(CD) driver;$(MAKE)) $(LD) $(LFLAGS) -o $(KERNEL) $(KOBJECTS) $(DD) if=$(BOOT).img bs=512 count=1 of=$(IMDISK) $(CP) $(LOADER) $(ADRIVE) $(CP) $(KERNEL) $(ADRIVE)
#------------------------------------------------------------------------------- # Clear Objects #-------------------------------------------------------------------------------
.PHONY: clean clean: $(RM) -f $(BOOT).img $(LOADER) $(KERNEL) ($(CD) driver; $(MAKE) clean) ($(CD) kernel; $(MAKE) clean)
#=============================================================================== # TARGETS #===============================================================================
BOOT = boot LOADER = STARTING.IMG LOADERASM = Starting.asm KERNEL = KImage KOBJECTS = kernel/krnl.o driver/driver.o
#=============================================================================== # DEFINES #===============================================================================
HOME_DIR = "$(CURDIR)" CC = i686-pc-linux-gnu-gcc CFLAGS = -fomit-frame-pointer -O2 -I$(HOME_DIR)/include -masm=intel -Wall ASFLAGS = -msyntax=intel -march=i686 --32 LFLAGS = -T linkerscript -Map kernel.map -nostdlib -e _kernel_entry --oformat binary ASM = nasm AS = i686-pc-linux-gnu-as LD = i686-pc-linux-gnu-ld DD = dd CP = cp RM = rm CD = cd MAKE = make IMDISK = /proc/sys/Device/ImDisk0 ADRIVE = /cygdrive/a export HOME_DIR export CC export CFLAGS export LD export ASFLAGS export AS
#=============================================================================== # RULES #=============================================================================== #------------------------------------------------------------------------------- # Kernel #-------------------------------------------------------------------------------
.PHONY: all all: $(BOOT).img $(LOADER) $(KERNEL) $(KOBJECTS) # ;Make kernel objects ($(CD) kernel;$(MAKE)) ($(CD) driver;$(MAKE)) # ;Make boot loader $(ASM) -o $(BOOT).img $(BOOT)/$(BOOT).asm $(ASM) -I$(BOOT) -o $(LOADER) $(BOOT)/$(LOADERASM) # ;Make kernel image $(LD) $(LFLAGS) -o $(KERNEL) $(KOBJECTS) $(BOOT).img:$(BOOT)/$(BOOT).asm $(ASM) -o $(BOOT).img $(BOOT)/$(BOOT).asm $(LOADER):$(BOOT)/$(LOADERASM) $(ASM) -I$(BOOT) -o $(LOADER) $(BOOT)/$(LOADERASM) kernel/krnl.o: ($(CD) kernel;$(MAKE)) driver/driver.o: ($(CD) driver;$(MAKE)) $(KERNEL):$(KOBJECTS) $(LD) $(LFLAGS) -o $(KERNEL) $(KOBJECTS)
#------------------------------------------------------------------------------- # Install Kernel #-------------------------------------------------------------------------------
.PHONY: install install: $(BOOT).img $(LOADER) $(KERNEL) $(ASM) -o $(BOOT).img $(BOOT)/$(BOOT).asm ($(CD) kernel;$(MAKE)) ($(CD) driver;$(MAKE)) $(LD) $(LFLAGS) -o $(KERNEL) $(KOBJECTS) $(DD) if=$(BOOT).img bs=512 count=1 of=$(IMDISK) $(CP) $(LOADER) $(ADRIVE) $(CP) $(KERNEL) $(ADRIVE)
#------------------------------------------------------------------------------- # Clear Objects #-------------------------------------------------------------------------------
.PHONY: clean clean: $(RM) -f $(BOOT).img $(LOADER) $(KERNEL) ($(CD) driver; $(MAKE) clean) ($(CD) kernel; $(MAKE) clean)
#------------------------------------------------------------------------------- # Clear Objects #-------------------------------------------------------------------------------
.PHONY: clean clean: $(RM) -f $(BOOT).img $(LOADER) $(KERNEL) ($(CD) driver; $(MAKE) clean) ($(CD) kernel; $(MAKE) clean)
#=============================================================================== # TARGETS #===============================================================================
KOBJECTS = krnl.o OBJECTS = kernel.o
#=============================================================================== # DEFINES #===============================================================================
INCLUDES = ../include
#=============================================================================== # RULES #===============================================================================
.PHONY: all all: $(KOBJECTS) $(LD) -r -o $(KOBJECTS) $(OBJECTS) .c.o: $(CC) $(CFLAGS) \ -c -o $*.o $< $(KOBJECTS):$(OBJECTS) $(LD) -r -o $(KOBJECTS) $(OBJECTS) .PHONY: clean clean: ($(CD) $(MEM_DIR);$(MAKE) clean) ($(CD) $(SCHED_DIR);$(MAKE) clean) $(RM) -f *.o
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :_kernel_entry Input :void Output :void Return :int Description :Kernel Core _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
int _kernel_entry( void ) { for( ;; ) { } }
make all
make install
unsigned int _TEXT_START = ( unsigned int )&_text_start;
unsigned int _TEXT_END = ( unsigned int )&_text_end;
unsigned int _BSS_START = ( unsigned int )&_bss_start;
unsigned int _BSS_END = ( unsigned int )&_bss_end;
extern unsigned int _TEXT_START;
extern unsigned int _TEXT_END;
extern unsigned int _BSS_START;
extern unsigned int _BSS_END;
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :kmemset Input :void *str < start address to set > unsigned char c < value for setting > int size < size of memory > Output :void Return :void Description :set value to memory _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
void kmemset( void *str, unsigned char c, int size ) { unsigned char *ptr = ( unsigned char * )str; const unsigned char ch = ( const unsigned char )c; while( size-- ) *ptr++ = ch; }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :initBSS Input :unsigned int kernel_bss_start < start address of bss section of kernel > int size < size of bss section > Output :void Return :void Description :initialize BSS section _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
void initBSS( unsigned int kernel_bss_start, int size ) { kmemset( ( void * )kernel_bss_start, 0x00, size ); }
/* --------------------------------------------------------------------- */ /* clear bss section of kernel */ /* --------------------------------------------------------------------- */
initBSS( _BSS_START, _BSS_END - _BSS_START );
0 [main] git 3756 fhandler_disk_file::fixup_mmap_after_fork: requested 0xFFEA0000 != 0x0 mem alloc base 0xFFEA0000, state 0x1000, size 20480, Win32 error 487
141 [main] git 3756 C:\cygwin\lib\git-core\git.exe: *** fatal error in forked process - recreate_mmaps_after_fork_failed
468 [main] git 3756 open_stackdumpfile: Dumping stack trace to git.exe.stackdump
0 [main] git 1528 fork: child -1 - forked process 3756 died unexpectedly, retry 0, exit code 256, errno 11
error: cannot fork() for ssh: Resource temporarily unavailable
fatal: unable to fork
このような場合.bash_profileの最後の方にでも次のように追加すると
export LANG=C
C:\Users\ユーザ名\VirtualBox VMs\MyOS(設定した仮想PC名)\Logs