49968


現在、[こちらのサイト](https://arjunsreedharan.org/post/99370248137/kernels-201-lets-
write-a-kernel-with-keyboard)を参考にOSを自作しています。

最終的にはマウスなども追加し、画面を操作できるようにしたいと考えています。  
しかし、qemuでVBEを利用するには上記のサイトのように`qemu-system-i386 -kernel
kernel`ではサポートされないらしく、GRUBなどでisoファイルを作成し、起動しないといけないようです。  
isoファイルは[このサイト](https://www.gnu.org/software/grub/manual/grub/html_node/Making-
a-GRUB-bootable-
CD_002dROM.html)を参考に作成し、QEMUで起動まではできたのですがキーボード入力ができなくなってしまいました。

multibootの設定は[このサイト](https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#boot_002eS)を読んで自分なりに設定してみたのですがサンプルのboot.Sに`.long
_edata`, `.long
_end`と書いてありますがそんなラベルどこにも見当たりません。これはどこを指しているのでしょうか？（私が使用しているのはGNUアセンブラではなくNASMなのでNASMのほうで教えてもらえると助かります）  
Multibootについて他のサンプルなどを調べてみましたがどれもマジックナンバー、フラグ、チェックサムまでしか実装していませんでした。  
テキストモード、グラフィックモードでのMultibootの設定をNASMで実装したサンプルを示してもらえないでしょうか？

以下は私が作成しているOSの一部です。

* * *

kernel.ld

[code]

    OUTPUT_FORMAT("elf32-i386")
    OUTPUT_ARCH(i386)
    ENTRY(start)
    SECTIONS
    {
        . = 0x100000;
        .text : { *(.text) }
        .data : { *(.data) }
        .bss  : { *(.bss) }
    }
    
[/code]

start.asm

[code]

    section .text
    GLOBAL start, multiboot_header, multiboot_entry
    EXTERN kmain
    start:
        jmp multiboot_entry
        align 4
    multiboot_header:
        dd 0x1badb002
        dd 0x0
        dd - (0x1badb002 + 0x0)
        dd multiboot_header
        dd start
        dd 0 ; よくわからない
        dd 0 ; よくわからない
        dd multiboot_entry
        dd 0
        dd 0
        dd 0
        dd 0
    multiboot_entry:
        cli
        mov esp, stack_space
        push ebx
        push eax
        call kmain
        hlt
    section .bss
    resb 8192
    stack_space:
    
[/code]

kmain.c

[code]

    #include "types.h"
    #include "defs.h"
    #include "int.h"
    #include "x86.h"
    
    void kmain(void)
    {
        idt_init();
        pic_init();
        pic_enable(IRQ_KBD);
    
        clean_screen();
        kprint("KERNEL TEST");
        newline();
        while(1);
    }
    
[/code]

**現在できていること**  
`qemu-system-i386 -kernel kernel`では文字を打つことができる。  
作成したISOファイルで起動すると **KERNEL TEST** という文字列を表示することはできる。（キーボードを押すと再起動がかかってしまう）

回答よろしくお願いします。


CC BY-SA 4.0
2018-11-04T07:12:57.413
49947
2018-11-05T00:12:18.460
24999
question
linux c assembly
Multibootの設定方法について


前半だけなら  
Q. `_edata` や `_end` って何っすか？  
A. 伝統的に UNIX 系のリンカが勝手に出力するシンボルです。  
<https://linuxjm.osdn.jp/html/LDP_man-pages/man3/end.3.html>  
アセンブラ上のシンボル先頭のアンダースコアを除くと C シンボルになるわけですが `edata` は初期値ありデータ領域の末尾 `end` は BSS
の末尾ということになっています。

cygwin で実験

[code]

    $ cat hoge.c
    #include <stdio.h>
    extern int etext, edata, end;
    int main() {
        printf("etext = %p\n", &etext);
        printf("edata = %p\n", &edata);
        printf("end   = %p\n", &end);
    }
    $ g++ hoge.c -Xlinker -Map=hoge.map
    $ ./a.exe
    etext=0x1004071a8
    edata=0x1004071a0
    end  =0x1004071a4
    $
    
[/code]

これらの自動生成シンボルは真にそういう変数があるわけではないので、アドレスを取ることはできても読み取りや書き込みをすることは厳禁です。リンク先解説にある通り、作られないこともあるので要注意。
`_edata` が見つかりませんと言われたら参照しないようにソース修正のこと。

(GNU ld の場合) `-Xlinker -Map=` で「マップファイル」を出力してみると `PROVIDE` という項目にこの `_etext` や
`_end` が自動的に作られていて実行前にアドレスを知ることができます（ `ASLR`
が有効だと実行時に表示される値は毎回変わるのでその辺を誤読しないことが重要）  
[Cygwinのg++で毎回、実行時に変数のアドレスが一緒になるのは何故？](https://ja.stackoverflow.com/questions/14337)


CC BY-SA 4.0
2018-11-05T00:12:18.460
49968
2018-11-05T00:12:18.460
8589
49947
answer