質問編集履歴
10
追記
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
set_gate関数IDT設定 関数が思うように動作しない。
|
1
|
+
解決しました。:set_gate関数IDT設定 関数が思うように動作しない。
|
test
CHANGED
File without changes
|
9
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -857,3 +857,29 @@
|
|
857
857
|
|
858
858
|
|
859
859
|
この場合エラーになります。(内容に関係なしに)
|
860
|
+
|
861
|
+
|
862
|
+
|
863
|
+
|
864
|
+
|
865
|
+
アセンブリ言語内で定義した関数は割り込みハンドラとして登録し実行することができる。
|
866
|
+
|
867
|
+
これを利用して解決案として
|
868
|
+
|
869
|
+
アセンブリ言語内で割り込みハンドラを登録。
|
870
|
+
|
871
|
+
そのハンドラ内でC言語関数アドレスに向けてJMPする。
|
872
|
+
|
873
|
+
|
874
|
+
|
875
|
+
・・・この方法を試そうと思いましたが
|
876
|
+
|
877
|
+
アセンブリ言語で書かれたブートローダーと
|
878
|
+
|
879
|
+
C言語で書かれたカーネルをそれぞれ
|
880
|
+
|
881
|
+
別々にリンクしrawバイナリ形式にしたところで繋げているのでこの方法は使えません・・・。
|
882
|
+
|
883
|
+
|
884
|
+
|
885
|
+
なんか解決策はないでしょうか?
|
8
ついき
test
CHANGED
File without changes
|
test
CHANGED
@@ -819,3 +819,41 @@
|
|
819
819
|
ブートローダーで上記のプログラムでIDTに登録したところうまくできましたが
|
820
820
|
|
821
821
|
カーネル以降での登録はまだうまくいっていません。
|
822
|
+
|
823
|
+
|
824
|
+
|
825
|
+
ブートローダーはアセンブリ言語で書き
|
826
|
+
|
827
|
+
カーネル以降はC言語で記述しており
|
828
|
+
|
829
|
+
|
830
|
+
|
831
|
+
アセンブリ言語で定義した関数を登録しソフトウエア割り込みで呼び出す分には何も問題なく作動するのですが
|
832
|
+
|
833
|
+
カーネルつまりC言語で定義された関数を登録すると呼び出した時点でエラー・暴走が起こります。
|
834
|
+
|
835
|
+
呼び出した時点で暴走するので関数から復帰する際に~ってわけではなさそうです。
|
836
|
+
|
837
|
+
|
838
|
+
|
839
|
+
void function(){}
|
840
|
+
|
841
|
+
|
842
|
+
|
843
|
+
なにもしなってのはこのようなやつです。
|
844
|
+
|
845
|
+
|
846
|
+
|
847
|
+
_set_gate(idt_address,14,0,ブートローダーアセンブリ言語レベルで定義した関数アドレス,0x08);
|
848
|
+
|
849
|
+
|
850
|
+
|
851
|
+
この場合はうまくいき
|
852
|
+
|
853
|
+
|
854
|
+
|
855
|
+
_set_gate(idt_address,14,0,カーネルCC言語レベルで定義すた関数アドレス,0x08);
|
856
|
+
|
857
|
+
|
858
|
+
|
859
|
+
この場合エラーになります。(内容に関係なしに)
|
7
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -793,3 +793,29 @@
|
|
793
793
|
そもそもIDTにトラップゲートを設置する以前に何か設定するものでもあるのでしょうか?
|
794
794
|
|
795
795
|
何か知っておられましたら教えていただけると助かります。
|
796
|
+
|
797
|
+
|
798
|
+
|
799
|
+
```
|
800
|
+
|
801
|
+
lidt [IDTR]
|
802
|
+
|
803
|
+
mov eax,int_handler
|
804
|
+
|
805
|
+
mov [IDT+49*8],ax
|
806
|
+
|
807
|
+
mov word [IDT+49*8+2],0x08
|
808
|
+
|
809
|
+
mov word [IDT+49*8+4],0x8E00
|
810
|
+
|
811
|
+
shr eax,16
|
812
|
+
|
813
|
+
mov [IDT+49*8+6],ax
|
814
|
+
|
815
|
+
int 49
|
816
|
+
|
817
|
+
```
|
818
|
+
|
819
|
+
ブートローダーで上記のプログラムでIDTに登録したところうまくできましたが
|
820
|
+
|
821
|
+
カーネル以降での登録はまだうまくいっていません。
|
6
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -789,3 +789,7 @@
|
|
789
789
|
```
|
790
790
|
|
791
791
|
こちらも結果は同様に変わりませんでした。(1万文字をこえるので変更点以外は省略しました。)
|
792
|
+
|
793
|
+
そもそもIDTにトラップゲートを設置する以前に何か設定するものでもあるのでしょうか?
|
794
|
+
|
795
|
+
何か知っておられましたら教えていただけると助かります。
|
5
追記yg7いg789
test
CHANGED
File without changes
|
test
CHANGED
@@ -392,18 +392,6 @@
|
|
392
392
|
|
393
393
|
void protect_puts(char*,int,int,int);
|
394
394
|
|
395
|
-
void KBC_sendready();
|
396
|
-
|
397
|
-
int in_kbc(int);
|
398
|
-
|
399
|
-
void out_kbc(int,int);
|
400
|
-
|
401
|
-
void set_keyboard();
|
402
|
-
|
403
|
-
void set_mouse();
|
404
|
-
|
405
|
-
void set_PIC_Hardware_interrupt();
|
406
|
-
|
407
395
|
void set_intr_gate();
|
408
396
|
|
409
397
|
void aaa();
|
@@ -424,14 +412,6 @@
|
|
424
412
|
|
425
413
|
|
426
414
|
|
427
|
-
set_PIC_Hardware_interrupt();
|
428
|
-
|
429
|
-
set_keyboard();
|
430
|
-
|
431
|
-
set_mouse();
|
432
|
-
|
433
|
-
|
434
|
-
|
435
415
|
__asm__(
|
436
416
|
|
437
417
|
"int $0x32\n\t"
|
@@ -690,157 +670,9 @@
|
|
690
670
|
|
691
671
|
|
692
672
|
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
void set_PIC_Hardware_interrupt(void){
|
698
|
-
|
699
|
-
out_kbc(0x21,0xff); /* マスタPIC 割り込みマスクレジスタ https://books.google.co.jp/books?id=ilSvAgAAQBAJ&pg=PA698&lpg=PA698&dq=30%E6%97%A5os+PIC0_IMR&source=bl&ots=k2QAHG49WB&sig=ACfU3U1p8v00GRN-FGlY4vhikh3HChjXvQ&hl=ja&sa=X&ved=2ahUKEwj-le-m86LoAhXFfd4KHXJ1DzUQ6AEwAHoECAoQAQ#v=onepage&q=30%E6%97%A5os%20PIC0_IMR&f=false */
|
700
|
-
|
701
|
-
out_kbc(0xa1,0xff); /* スレーブPIC 割り込みマスクレジスタ http://softwaretechnique.jp/OS_Development/kernel_development03.html*/
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
out_kbc(0x20,0x11);
|
706
|
-
|
707
|
-
out_kbc(0x20,0x20); /* IRQ0~IRQ7 INT20~INT27 */
|
708
|
-
|
709
|
-
out_kbc(0x21,1<<2);
|
710
|
-
|
711
|
-
out_kbc(0x21,0x01);
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
out_kbc(0xa0,0x11);
|
716
|
-
|
717
|
-
out_kbc(0xa0,0x28); /* IRQ8~IRQ15 INT28~INT2f */
|
718
|
-
|
719
|
-
out_kbc(0xa1,2);
|
720
|
-
|
721
|
-
out_kbc(0xa1,0x01);
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
/* out_kbc(0x21,0xfb);
|
726
|
-
|
727
|
-
out_kbc(0xa1,0xff); */
|
728
|
-
|
729
|
-
}
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
/* マウス有効化関数 */
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
void set_mouse(void){
|
738
|
-
|
739
|
-
KBC_sendready();
|
740
|
-
|
741
|
-
out_kbc(0x64,0xd4); /* 0xd4??? */
|
742
|
-
|
743
|
-
KBC_sendready();
|
744
|
-
|
745
|
-
out_kbc(0x60,0xf4);
|
746
|
-
|
747
|
-
}
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
/* キーボード初期化・有効化関数 */
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
void set_keyboard(void){
|
756
|
-
|
757
|
-
KBC_sendready();
|
758
|
-
|
759
|
-
out_kbc(0x64,0x60); /* 0x60 ??? */
|
760
|
-
|
761
|
-
KBC_sendready();
|
762
|
-
|
763
|
-
out_kbc(0x64,0x47); /* 0x47 ??? */
|
764
|
-
|
765
|
-
}
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
/* KBCコントローラーへデータを送れるかどうかを判断する。 */
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
void KBC_sendready(void){
|
774
|
-
|
775
|
-
for(;;){
|
776
|
-
|
777
|
-
if((in_kbc(0x64)) == 0){
|
778
|
-
|
779
|
-
break;
|
780
|
-
|
781
|
-
}
|
782
|
-
|
783
|
-
}
|
784
|
-
|
785
|
-
}
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
/* IN KBC ステータスレジスタなど取得関数 */
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
int in_kbc(int in_number){
|
794
|
-
|
795
|
-
int return_status = 0;
|
796
|
-
|
797
|
-
__asm__ __volatile__(
|
798
|
-
|
799
|
-
"mov %0,%%edx\n\t"
|
800
|
-
|
801
|
-
"xor %%eax,%%eax\n\t"
|
802
|
-
|
803
|
-
"in %%dx,%%al\n\t"
|
804
|
-
|
805
|
-
"mov %%al,%0\n\t"
|
806
|
-
|
807
|
-
:"=m" (return_status)
|
808
|
-
|
809
|
-
:"m" (in_number)
|
810
|
-
|
811
|
-
);
|
812
|
-
|
813
|
-
return return_status;
|
814
|
-
|
815
|
-
}
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
/* OUT KBC */
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
void out_kbc(int out_number,int data){
|
824
|
-
|
825
|
-
__asm__ __volatile__(
|
826
|
-
|
827
|
-
"mov %2,%%edx\n\t"
|
828
|
-
|
829
|
-
"mov %3,%%eax\n\t"
|
830
|
-
|
831
|
-
"out %%al,%%dx\n\t"
|
832
|
-
|
833
|
-
:"=m" (out_number),
|
834
|
-
|
835
|
-
"=m" (data)
|
836
|
-
|
837
|
-
:"m" (out_number),
|
838
|
-
|
839
|
-
"m" (data)
|
840
|
-
|
841
|
-
);
|
842
|
-
|
843
|
-
}
|
673
|
+
|
674
|
+
|
675
|
+
|
844
676
|
|
845
677
|
|
846
678
|
|
@@ -866,8 +698,94 @@
|
|
866
698
|
|
867
699
|
|
868
700
|
|
869
|
-
省略
|
701
|
+
文字制限のためPIC初期化関数とかは省略しました。main_kernelから処理がスタートします。
|
870
702
|
|
871
703
|
INT 0x32(10進数50)でaaa関数を呼び出そうとしています。
|
872
704
|
|
873
705
|
(何やら長いですが原因が全く分からないのでお願いします・・・。)
|
706
|
+
|
707
|
+
|
708
|
+
|
709
|
+
**やってみたこと**
|
710
|
+
|
711
|
+
|
712
|
+
|
713
|
+
IDTアドレスの指定が間違えている可能性がある。
|
714
|
+
|
715
|
+
なので・・・
|
716
|
+
|
717
|
+
ブートローダーからカーネルへ制御が移行する際に
|
718
|
+
|
719
|
+
|
720
|
+
|
721
|
+
push IDT
|
722
|
+
|
723
|
+
|
724
|
+
|
725
|
+
とすることでスタックにIDTアドレスを保管し
|
726
|
+
|
727
|
+
カーネルに制御が移ったらスタックに積まれたアドレスを回収する。
|
728
|
+
|
729
|
+
```c
|
730
|
+
|
731
|
+
/* プロトタイプ宣言 0x1060 */
|
732
|
+
|
733
|
+
void loop();
|
734
|
+
|
735
|
+
void protect_puts(char*,int,int,int);
|
736
|
+
|
737
|
+
void set_intr_gate(int);
|
738
|
+
|
739
|
+
void aaa();
|
740
|
+
|
741
|
+
void test();
|
742
|
+
|
743
|
+
|
744
|
+
|
745
|
+
|
746
|
+
|
747
|
+
/* メイン関数 */
|
748
|
+
|
749
|
+
|
750
|
+
|
751
|
+
void main_kernel(){
|
752
|
+
|
753
|
+
int idt_address = 0x00000000;
|
754
|
+
|
755
|
+
__asm__(
|
756
|
+
|
757
|
+
"mov 4(%%esp),%%eax\n\t"
|
758
|
+
|
759
|
+
"mov %%eax,%1\n\t"
|
760
|
+
|
761
|
+
:"=m" (idt_address)
|
762
|
+
|
763
|
+
:"m" (idt_address)
|
764
|
+
|
765
|
+
);
|
766
|
+
|
767
|
+
|
768
|
+
|
769
|
+
set_intr_gate(idt_address);
|
770
|
+
|
771
|
+
}
|
772
|
+
|
773
|
+
|
774
|
+
|
775
|
+
void set_intr_gate(int idt_address)
|
776
|
+
|
777
|
+
{
|
778
|
+
|
779
|
+
void(* a)() = aaa;
|
780
|
+
|
781
|
+
_set_gate(idt_address,14,0,&a,0x08); /* 0x8600 */
|
782
|
+
|
783
|
+
}
|
784
|
+
|
785
|
+
|
786
|
+
|
787
|
+
|
788
|
+
|
789
|
+
```
|
790
|
+
|
791
|
+
こちらも結果は同様に変わりませんでした。(1万文字をこえるので変更点以外は省略しました。)
|
4
追記
test
CHANGED
File without changes
|
test
CHANGED
File without changes
|
3
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -381,3 +381,493 @@
|
|
381
381
|
アセンブリ言語でいうところのret命令みたいのが必要なのでしょうか?
|
382
382
|
|
383
383
|
(いや、それだったらエラーになるはずだが・・・)
|
384
|
+
|
385
|
+
|
386
|
+
|
387
|
+
```c
|
388
|
+
|
389
|
+
/* プロトタイプ宣言 0x1060 */
|
390
|
+
|
391
|
+
void loop();
|
392
|
+
|
393
|
+
void protect_puts(char*,int,int,int);
|
394
|
+
|
395
|
+
void KBC_sendready();
|
396
|
+
|
397
|
+
int in_kbc(int);
|
398
|
+
|
399
|
+
void out_kbc(int,int);
|
400
|
+
|
401
|
+
void set_keyboard();
|
402
|
+
|
403
|
+
void set_mouse();
|
404
|
+
|
405
|
+
void set_PIC_Hardware_interrupt();
|
406
|
+
|
407
|
+
void set_intr_gate();
|
408
|
+
|
409
|
+
void aaa();
|
410
|
+
|
411
|
+
|
412
|
+
|
413
|
+
/* メイン関数 */
|
414
|
+
|
415
|
+
|
416
|
+
|
417
|
+
void main_kernel(){
|
418
|
+
|
419
|
+
|
420
|
+
|
421
|
+
set_intr_gate();
|
422
|
+
|
423
|
+
|
424
|
+
|
425
|
+
|
426
|
+
|
427
|
+
set_PIC_Hardware_interrupt();
|
428
|
+
|
429
|
+
set_keyboard();
|
430
|
+
|
431
|
+
set_mouse();
|
432
|
+
|
433
|
+
|
434
|
+
|
435
|
+
__asm__(
|
436
|
+
|
437
|
+
"int $0x32\n\t"
|
438
|
+
|
439
|
+
);
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
loop();
|
444
|
+
|
445
|
+
|
446
|
+
|
447
|
+
}
|
448
|
+
|
449
|
+
|
450
|
+
|
451
|
+
|
452
|
+
|
453
|
+
|
454
|
+
|
455
|
+
|
456
|
+
|
457
|
+
void aaa(){
|
458
|
+
|
459
|
+
char ptr[] = "abcdefghigk";
|
460
|
+
|
461
|
+
char *a = ptr;
|
462
|
+
|
463
|
+
protect_puts(a,11,5,5);
|
464
|
+
|
465
|
+
|
466
|
+
|
467
|
+
}
|
468
|
+
|
469
|
+
|
470
|
+
|
471
|
+
/* 文字表示関数 */
|
472
|
+
|
473
|
+
|
474
|
+
|
475
|
+
void protect_puts(char *char_address,int bytes,int side_size,int height_size){ /* 1=文字アドレス,2=バイト */
|
476
|
+
|
477
|
+
|
478
|
+
|
479
|
+
|
480
|
+
|
481
|
+
int vram_address = 0xA0000;
|
482
|
+
|
483
|
+
int font_address = 0x0500;
|
484
|
+
|
485
|
+
int byte_count = bytes;
|
486
|
+
|
487
|
+
int yoko = side_size;
|
488
|
+
|
489
|
+
int tate = height_size;
|
490
|
+
|
491
|
+
char *ptrr = char_address;
|
492
|
+
|
493
|
+
|
494
|
+
|
495
|
+
__asm__ __volatile__(
|
496
|
+
|
497
|
+
/* 横設定 */
|
498
|
+
|
499
|
+
"mov %7,%%eax\n\t"
|
500
|
+
|
501
|
+
"mov %5,%%ebx\n\t"
|
502
|
+
|
503
|
+
"add %%eax,%%ebx\n\t"
|
504
|
+
|
505
|
+
"mov %%ebx,%2\n\t"
|
506
|
+
|
507
|
+
|
508
|
+
|
509
|
+
|
510
|
+
|
511
|
+
"mov %8,%%eax\n\t"
|
512
|
+
|
513
|
+
"mov $1280,%%ebx\n\t"
|
514
|
+
|
515
|
+
"mul %%ebx\n\t"
|
516
|
+
|
517
|
+
"mov %5,%%ebx\n\t"
|
518
|
+
|
519
|
+
"add %%eax,%%ebx\n\t"
|
520
|
+
|
521
|
+
"mov %%ebx,%2\n\t"
|
522
|
+
|
523
|
+
|
524
|
+
|
525
|
+
|
526
|
+
|
527
|
+
"mov %6,%%eax\n\t" /* eax = 文字があるアドレス */
|
528
|
+
|
529
|
+
"mov %3,%%ebx\n\t" /* %0 ebx = バイト数 */
|
530
|
+
|
531
|
+
".protect_puts_loop2:\n\t"
|
532
|
+
|
533
|
+
"cmp $0,%%ebx\n\t"
|
534
|
+
|
535
|
+
"jz .endd\n\t"
|
536
|
+
|
537
|
+
|
538
|
+
|
539
|
+
"xor %%esi,%%esi\n\t"
|
540
|
+
|
541
|
+
"mov (%%eax),%%esi\n\t" /* esiレジスタにASCII1文字 */
|
542
|
+
|
543
|
+
/* "mov $97,%%esi\n\t" */
|
544
|
+
|
545
|
+
"and $0b00000000000000000000000011111111,%%esi\n\t"
|
546
|
+
|
547
|
+
"shl $4,%%esi\n\t"
|
548
|
+
|
549
|
+
|
550
|
+
|
551
|
+
"xor %%ebx,%%ebx\n\t"
|
552
|
+
|
553
|
+
"mov %4,%%ebx\n\t"
|
554
|
+
|
555
|
+
"add %%ebx,%%esi\n\t"
|
556
|
+
|
557
|
+
|
558
|
+
|
559
|
+
|
560
|
+
|
561
|
+
"mov %5,%%edi\n\t"
|
562
|
+
|
563
|
+
|
564
|
+
|
565
|
+
"mov $16,%%ecx\n\t" /* 1文字 縦16bitだから */
|
566
|
+
|
567
|
+
|
568
|
+
|
569
|
+
".protect_puts_loop:\n\t"
|
570
|
+
|
571
|
+
"movsb\n\t"
|
572
|
+
|
573
|
+
"add $80 - 1,%%edi\n\t"
|
574
|
+
|
575
|
+
"loop .protect_puts_loop\n\t"
|
576
|
+
|
577
|
+
|
578
|
+
|
579
|
+
"inc %%eax\n\t"
|
580
|
+
|
581
|
+
|
582
|
+
|
583
|
+
"xor %%ebx,%%ebx\n\t"
|
584
|
+
|
585
|
+
|
586
|
+
|
587
|
+
"mov %5,%%ebx\n\t"
|
588
|
+
|
589
|
+
"add $1,%%ebx\n\t"
|
590
|
+
|
591
|
+
"mov %%ebx,%2\n\t"
|
592
|
+
|
593
|
+
|
594
|
+
|
595
|
+
"mov %3,%%ebx\n\t" /* バイトカウント 0かどうか確認 */
|
596
|
+
|
597
|
+
"sub $1,%%ebx\n\t"
|
598
|
+
|
599
|
+
"mov %%ebx,%0\n\t"
|
600
|
+
|
601
|
+
"mov %3,%%ebx\n\t"/* 変更 */
|
602
|
+
|
603
|
+
|
604
|
+
|
605
|
+
"jmp .protect_puts_loop2\n\t"
|
606
|
+
|
607
|
+
|
608
|
+
|
609
|
+
|
610
|
+
|
611
|
+
".endd:\n\t"
|
612
|
+
|
613
|
+
|
614
|
+
|
615
|
+
|
616
|
+
|
617
|
+
: "=m" (byte_count), /* %0 バイト数 */
|
618
|
+
|
619
|
+
"=m" (font_address),
|
620
|
+
|
621
|
+
"=m" (vram_address)
|
622
|
+
|
623
|
+
|
624
|
+
|
625
|
+
: "m" (byte_count), /* %0 バイト数 %4*/
|
626
|
+
|
627
|
+
"m" (font_address),
|
628
|
+
|
629
|
+
"m" (vram_address),
|
630
|
+
|
631
|
+
"m" (ptrr),
|
632
|
+
|
633
|
+
"m" (yoko),
|
634
|
+
|
635
|
+
"m" (tate)
|
636
|
+
|
637
|
+
);
|
638
|
+
|
639
|
+
|
640
|
+
|
641
|
+
}
|
642
|
+
|
643
|
+
|
644
|
+
|
645
|
+
|
646
|
+
|
647
|
+
|
648
|
+
|
649
|
+
/* IDT登録関数 */
|
650
|
+
|
651
|
+
|
652
|
+
|
653
|
+
#define _set_gate(gate_addr,type,dpl,addr,seg) \
|
654
|
+
|
655
|
+
do { \
|
656
|
+
|
657
|
+
int __d0, __d1; \
|
658
|
+
|
659
|
+
__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
|
660
|
+
|
661
|
+
"movw %4,%%dx\n\t" \
|
662
|
+
|
663
|
+
"movl %%eax,%0\n\t" \
|
664
|
+
|
665
|
+
"movl %%edx,%1" \
|
666
|
+
|
667
|
+
:"=m" (*((long *) (gate_addr))), \
|
668
|
+
|
669
|
+
"=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
|
670
|
+
|
671
|
+
:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
|
672
|
+
|
673
|
+
"3" ((char *) (addr)),"2" ((seg) << 16)); \
|
674
|
+
|
675
|
+
} while (0)
|
676
|
+
|
677
|
+
|
678
|
+
|
679
|
+
void set_intr_gate()
|
680
|
+
|
681
|
+
{
|
682
|
+
|
683
|
+
void(* a)() = aaa;
|
684
|
+
|
685
|
+
_set_gate(0x8590,14,0,&a,0x08); /* 0x8600 */
|
686
|
+
|
687
|
+
}
|
688
|
+
|
689
|
+
|
690
|
+
|
691
|
+
|
692
|
+
|
693
|
+
/* PIC ハードウエア割り込みと割り込み処理ルーチンを結び付ける。 */
|
694
|
+
|
695
|
+
|
696
|
+
|
697
|
+
void set_PIC_Hardware_interrupt(void){
|
698
|
+
|
699
|
+
out_kbc(0x21,0xff); /* マスタPIC 割り込みマスクレジスタ https://books.google.co.jp/books?id=ilSvAgAAQBAJ&pg=PA698&lpg=PA698&dq=30%E6%97%A5os+PIC0_IMR&source=bl&ots=k2QAHG49WB&sig=ACfU3U1p8v00GRN-FGlY4vhikh3HChjXvQ&hl=ja&sa=X&ved=2ahUKEwj-le-m86LoAhXFfd4KHXJ1DzUQ6AEwAHoECAoQAQ#v=onepage&q=30%E6%97%A5os%20PIC0_IMR&f=false */
|
700
|
+
|
701
|
+
out_kbc(0xa1,0xff); /* スレーブPIC 割り込みマスクレジスタ http://softwaretechnique.jp/OS_Development/kernel_development03.html*/
|
702
|
+
|
703
|
+
|
704
|
+
|
705
|
+
out_kbc(0x20,0x11);
|
706
|
+
|
707
|
+
out_kbc(0x20,0x20); /* IRQ0~IRQ7 INT20~INT27 */
|
708
|
+
|
709
|
+
out_kbc(0x21,1<<2);
|
710
|
+
|
711
|
+
out_kbc(0x21,0x01);
|
712
|
+
|
713
|
+
|
714
|
+
|
715
|
+
out_kbc(0xa0,0x11);
|
716
|
+
|
717
|
+
out_kbc(0xa0,0x28); /* IRQ8~IRQ15 INT28~INT2f */
|
718
|
+
|
719
|
+
out_kbc(0xa1,2);
|
720
|
+
|
721
|
+
out_kbc(0xa1,0x01);
|
722
|
+
|
723
|
+
|
724
|
+
|
725
|
+
/* out_kbc(0x21,0xfb);
|
726
|
+
|
727
|
+
out_kbc(0xa1,0xff); */
|
728
|
+
|
729
|
+
}
|
730
|
+
|
731
|
+
|
732
|
+
|
733
|
+
/* マウス有効化関数 */
|
734
|
+
|
735
|
+
|
736
|
+
|
737
|
+
void set_mouse(void){
|
738
|
+
|
739
|
+
KBC_sendready();
|
740
|
+
|
741
|
+
out_kbc(0x64,0xd4); /* 0xd4??? */
|
742
|
+
|
743
|
+
KBC_sendready();
|
744
|
+
|
745
|
+
out_kbc(0x60,0xf4);
|
746
|
+
|
747
|
+
}
|
748
|
+
|
749
|
+
|
750
|
+
|
751
|
+
/* キーボード初期化・有効化関数 */
|
752
|
+
|
753
|
+
|
754
|
+
|
755
|
+
void set_keyboard(void){
|
756
|
+
|
757
|
+
KBC_sendready();
|
758
|
+
|
759
|
+
out_kbc(0x64,0x60); /* 0x60 ??? */
|
760
|
+
|
761
|
+
KBC_sendready();
|
762
|
+
|
763
|
+
out_kbc(0x64,0x47); /* 0x47 ??? */
|
764
|
+
|
765
|
+
}
|
766
|
+
|
767
|
+
|
768
|
+
|
769
|
+
/* KBCコントローラーへデータを送れるかどうかを判断する。 */
|
770
|
+
|
771
|
+
|
772
|
+
|
773
|
+
void KBC_sendready(void){
|
774
|
+
|
775
|
+
for(;;){
|
776
|
+
|
777
|
+
if((in_kbc(0x64)) == 0){
|
778
|
+
|
779
|
+
break;
|
780
|
+
|
781
|
+
}
|
782
|
+
|
783
|
+
}
|
784
|
+
|
785
|
+
}
|
786
|
+
|
787
|
+
|
788
|
+
|
789
|
+
/* IN KBC ステータスレジスタなど取得関数 */
|
790
|
+
|
791
|
+
|
792
|
+
|
793
|
+
int in_kbc(int in_number){
|
794
|
+
|
795
|
+
int return_status = 0;
|
796
|
+
|
797
|
+
__asm__ __volatile__(
|
798
|
+
|
799
|
+
"mov %0,%%edx\n\t"
|
800
|
+
|
801
|
+
"xor %%eax,%%eax\n\t"
|
802
|
+
|
803
|
+
"in %%dx,%%al\n\t"
|
804
|
+
|
805
|
+
"mov %%al,%0\n\t"
|
806
|
+
|
807
|
+
:"=m" (return_status)
|
808
|
+
|
809
|
+
:"m" (in_number)
|
810
|
+
|
811
|
+
);
|
812
|
+
|
813
|
+
return return_status;
|
814
|
+
|
815
|
+
}
|
816
|
+
|
817
|
+
|
818
|
+
|
819
|
+
/* OUT KBC */
|
820
|
+
|
821
|
+
|
822
|
+
|
823
|
+
void out_kbc(int out_number,int data){
|
824
|
+
|
825
|
+
__asm__ __volatile__(
|
826
|
+
|
827
|
+
"mov %2,%%edx\n\t"
|
828
|
+
|
829
|
+
"mov %3,%%eax\n\t"
|
830
|
+
|
831
|
+
"out %%al,%%dx\n\t"
|
832
|
+
|
833
|
+
:"=m" (out_number),
|
834
|
+
|
835
|
+
"=m" (data)
|
836
|
+
|
837
|
+
:"m" (out_number),
|
838
|
+
|
839
|
+
"m" (data)
|
840
|
+
|
841
|
+
);
|
842
|
+
|
843
|
+
}
|
844
|
+
|
845
|
+
|
846
|
+
|
847
|
+
/* ループ関数 */
|
848
|
+
|
849
|
+
|
850
|
+
|
851
|
+
void loop(){
|
852
|
+
|
853
|
+
|
854
|
+
|
855
|
+
for(; ; ) {
|
856
|
+
|
857
|
+
|
858
|
+
|
859
|
+
}
|
860
|
+
|
861
|
+
}
|
862
|
+
|
863
|
+
|
864
|
+
|
865
|
+
```
|
866
|
+
|
867
|
+
|
868
|
+
|
869
|
+
省略なしの全コードです。main_kernelから処理がスタートします。
|
870
|
+
|
871
|
+
INT 0x32(10進数50)でaaa関数を呼び出そうとしています。
|
872
|
+
|
873
|
+
(何やら長いですが原因が全く分からないのでお願いします・・・。)
|
2
追記
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
set_gate関数
|
1
|
+
set_gate関数IDT設定 関数が思うように動作しない。
|
test
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
(内容が乱雑だったので訂正しました。)
|
2
|
+
|
1
3
|
IDTのゲートディスクリプタにはaaa関数を登録します。
|
2
4
|
|
3
|
-
|
5
|
+
|
4
6
|
|
5
7
|
```c
|
6
8
|
|
@@ -10,6 +12,8 @@
|
|
10
12
|
|
11
13
|
void aaa();
|
12
14
|
|
15
|
+
void loop();
|
16
|
+
|
13
17
|
|
14
18
|
|
15
19
|
/* メイン関数 */
|
@@ -30,13 +34,25 @@
|
|
30
34
|
|
31
35
|
);
|
32
36
|
|
33
|
-
|
37
|
+
loop();
|
34
|
-
|
38
|
+
|
39
|
+
|
40
|
+
|
35
|
-
}
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
|
36
|
-
|
45
|
+
void loop(){
|
46
|
+
|
47
|
+
|
48
|
+
|
37
|
-
|
49
|
+
for(; ; ) {
|
50
|
+
|
51
|
+
|
52
|
+
|
38
|
-
|
53
|
+
}
|
54
|
+
|
39
|
-
|
55
|
+
}
|
40
56
|
|
41
57
|
|
42
58
|
|
@@ -264,19 +280,9 @@
|
|
264
280
|
|
265
281
|
a = aaa;
|
266
282
|
|
267
|
-
|
283
|
+
|
268
|
-
|
269
|
-
|
284
|
+
|
270
|
-
|
271
|
-
"IDTR:\n\t"
|
272
|
-
|
273
|
-
".word 0x0200\n\t"
|
274
|
-
|
275
|
-
".word 0x8400\n\t"
|
276
|
-
|
277
|
-
);
|
278
|
-
|
279
|
-
_set_gate(0x8400,14,0,
|
285
|
+
_set_gate(0x8400,14,0,&a,0x08);
|
280
286
|
|
281
287
|
}
|
282
288
|
|
@@ -284,382 +290,94 @@
|
|
284
290
|
|
285
291
|
```
|
286
292
|
|
287
|
-
[
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
② _set_gate(0x8400,14,0,*a,0x08);
|
380
|
-
|
381
|
-
_set_gate関数を呼び出しています。
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
「0x8400」・・・ IDTアドレス(INT 0x00で呼び出したいから一番最初にセットする。)
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
「0」・・・dpl
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
「*a」・・・aaa関数のポインタ
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
「0x08」・・・GDT セグメントディスクリプタ(コード)
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
GDT:
|
402
|
-
|
403
|
-
dq 0x00_0_0_0_0_000000_0000 ;NULLディスクリプタ―
|
404
|
-
|
405
|
-
.cs: dq 0x00_C_F_9_A_000000_FFFF ;コードディスクリプター
|
406
|
-
|
407
|
-
.ds: dq 0x00_C_F_9_2_000000_FFFF ;データディスクリプタ―
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
上から2番目のやつを使用したいのでオフセット0x08を選びました。
|
412
|
-
|
413
|
-
(一応、0x01のパターンも試した)
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
上記の手順でIDTにゲートディスクリプタを設置しました。
|
418
|
-
|
419
|
-
いざ、__asm__(
|
420
|
-
|
421
|
-
"INT $0x00\n\t"
|
422
|
-
|
423
|
-
);
|
424
|
-
|
425
|
-
でソフトウエア割り込みを発生されるとプログラムが強制終了となります。
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
原因として
|
430
|
-
|
431
|
-
1 IDTRレジスタにIDTの情報を渡せていない。
|
432
|
-
|
433
|
-
2 そもそもset_gate関数が使えない
|
434
|
-
|
435
|
-
3 set_gate関数の引数が間違えており適切なゲートディスクリプタがIDTに設置できていない。
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
とかがあると思いますが・・・
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
しっかりプロトタイプ宣言もしていますし(マクロ関数は必要なのか・・・?)
|
444
|
-
|
445
|
-
呼び出し方もあっているはず(たぶん)
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
どこが間違えているのでしょうか?
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
### 自分でIDT登録関数を作ってみた
|
454
|
-
|
455
|
-
ゲートのフォーマット
|
456
|
-
|
457
|
-
[リンク内容](http://softwaretechnique.jp/OS_Development/kernel_development02.html)
|
458
|
-
|
459
|
-
```c
|
460
|
-
|
461
|
-
void set_intr_gate()
|
462
|
-
|
463
|
-
{
|
464
|
-
|
465
|
-
int b = 割り込み処理ルーチン先頭アドレス;
|
466
|
-
|
467
|
-
__asm__(
|
468
|
-
|
469
|
-
/* IDT再設定 */
|
470
|
-
|
471
|
-
"lidt IDTR\n\t"
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
"mov $IDTアドレス + 0,%%ebx\n\t" /* 下位16bitオフセット */
|
480
|
-
|
481
|
-
"mov %1,%%eax\n\t"
|
482
|
-
|
483
|
-
"mov %%ax,(%%ebx)\n\t"
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
"mov $IDTアドレス + 0x10,%%ebx\n\t" /* セグメントセレクター */
|
488
|
-
|
489
|
-
"mov $0x08,%%eax\n\t"
|
490
|
-
|
491
|
-
"mov %%ax,(%%ebx)\n\t"
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
"mov $IDTアドレス + 0x20,%%ebx\n\t" /* DPLとか・・・ */
|
496
|
-
|
497
|
-
"mov $0b11110111100000000,%%eax\n\t"
|
498
|
-
|
499
|
-
"mov %%ax,(%%ebx)\n\t"
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
"mov $IDTアドレス + 0x30,%%ebx\n\t" /* 上位16bitオフセット */
|
504
|
-
|
505
|
-
"mov %1,%%eax\n\t"
|
506
|
-
|
507
|
-
"shr $16,%%eax\n\t"
|
508
|
-
|
509
|
-
"mov %%ax,(%%ebx)\n\t"
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
"jmp .end\n\t"
|
518
|
-
|
519
|
-
"IDTR:\n\t"
|
520
|
-
|
521
|
-
".word 0xIDTサイズ\n\t"
|
522
|
-
|
523
|
-
".word 0x0000\n\t"
|
524
|
-
|
525
|
-
".word 0xIDTアドレス\n\t"
|
526
|
-
|
527
|
-
".end:\n\t"
|
528
|
-
|
529
|
-
:"=m" (b)
|
530
|
-
|
531
|
-
:"m" (b)
|
532
|
-
|
533
|
-
);
|
534
|
-
|
535
|
-
}
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
```
|
540
|
-
|
541
|
-
割り込み処理ルーチン
|
542
|
-
|
543
|
-
```s
|
544
|
-
|
545
|
-
times (512 * 10) - ($ - $$) db 0x00
|
546
|
-
|
547
|
-
jmp $
|
548
|
-
|
549
|
-
```
|
550
|
-
|
551
|
-
10セクター目に jmp $ を設置しました。これをソフトウエア割り込みで呼び出せるようにしたいです。
|
552
|
-
|
553
|
-
(これで正しく動くかはわからないが・・・)
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
10セクターなので・・・
|
558
|
-
|
559
|
-
0x200(512)× 0x0A(10) + 0x7C00(ロードされるアドレス) = 0x9000
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
IDT
|
564
|
-
|
565
|
-
"lidt IDTR\n\t"
|
566
|
-
|
567
|
-
"IDTR:\n\t"
|
568
|
-
|
569
|
-
".word 0x0200\n\t"
|
570
|
-
|
571
|
-
".word 0x8400\n\t"
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
より、0x8400からIDTを開始させているつもりです。
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
```c
|
580
|
-
|
581
|
-
void set_intr_gate()
|
582
|
-
|
583
|
-
{
|
584
|
-
|
585
|
-
void(* a)();
|
586
|
-
|
587
|
-
a = aaa;
|
588
|
-
|
589
|
-
int b = 0x9000;
|
590
|
-
|
591
|
-
/* int b = 0x9C00; */
|
592
|
-
|
593
|
-
__asm__(
|
594
|
-
|
595
|
-
/* IDT再設定 */
|
596
|
-
|
597
|
-
"lidt IDTR\n\t"
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
/* ゲートディスクリプタを作成 */
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
"mov $0x8400,%%ebx\n\t" /* 下位16bitオフセット */
|
606
|
-
|
607
|
-
"mov %1,%%eax\n\t"
|
608
|
-
|
609
|
-
"mov %%ax,(%%ebx)\n\t"
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
"mov $0x8410,%%ebx\n\t" /* セグメントセレクター */
|
614
|
-
|
615
|
-
"mov $0x08,%%eax\n\t"
|
616
|
-
|
617
|
-
"mov %%ax,(%%ebx)\n\t"
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
"mov $0x8420,%%ebx\n\t" /* DPLとか・・・ */
|
622
|
-
|
623
|
-
"mov $0b11110111100000000,%%eax\n\t"
|
624
|
-
|
625
|
-
"mov %%ax,(%%ebx)\n\t"
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
"mov $0x8430,%%ebx\n\t" /* 上位16bitオフセット */
|
630
|
-
|
631
|
-
"mov %1,%%eax\n\t"
|
632
|
-
|
633
|
-
"shr $16,%%eax\n\t"
|
634
|
-
|
635
|
-
"mov %%ax,(%%ebx)\n\t"
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
"jmp .end\n\t"
|
644
|
-
|
645
|
-
"IDTR:"
|
646
|
-
|
647
|
-
".word 0x0200\n\t"
|
648
|
-
|
649
|
-
".word 0x0000\n\t"
|
650
|
-
|
651
|
-
".word 0x8400\n\t"
|
652
|
-
|
653
|
-
".end:\n\t"
|
654
|
-
|
655
|
-
:"=m" (b)
|
656
|
-
|
657
|
-
:"m" (b)
|
658
|
-
|
659
|
-
);
|
660
|
-
|
661
|
-
```
|
662
|
-
|
663
|
-
実行してみるものもまだエラーになります。
|
664
|
-
|
665
|
-
IDT開始アドレスの定義がおかしいのか、それとも割り込み処理ルーチンアドレスの設定が間違えているのか・・・。
|
293
|
+
[LinuxカーネルからIDT登録関数を持ってきました。](https://elixir.bootlin.com/linux/v2.6.17.8/source/arch/i386/kernel/traps.c#L1090)
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
ブートローダープログラムと上記のカーネル(?)プログラムをrawバイナリ形式に変換し
|
298
|
+
|
299
|
+
くっつけてVirtualbox上で動かします。
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
_set_gate(0x8400,14,0,&a,0x08);
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
これでIDTにゲートディスクリプタの登録を行っています。
|
308
|
+
|
309
|
+
このプログラムを使ってaaa関数(ポインタaにaaa関数のアドレスが入っている。)
|
310
|
+
|
311
|
+
をソフトウエア割り込みで呼び出せるようにしたいです。
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
aaa関数の中で画面に文字を表示させる関数を読んでいるので
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
ソフトウエア割り込み(INT 0x00)
|
320
|
+
|
321
|
+
↓
|
322
|
+
|
323
|
+
登録したゲートディスクリプタ(aaa関数への)が参照されaaa関数が呼ばれる。
|
324
|
+
|
325
|
+
↓
|
326
|
+
|
327
|
+
aaa関数内部で画面に文字が表示される関数が呼ばれ
|
328
|
+
|
329
|
+
画面上に文字が表示される。
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
以上のことを期待しています。
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
試験的に メモリ0x8600上に
|
338
|
+
|
339
|
+
jmp $(無限ループ)
|
340
|
+
|
341
|
+
この命令を配置し、
|
342
|
+
|
343
|
+
_set_gate(0x8400,14,0,0x8600,0x08);
|
344
|
+
|
345
|
+
とやってINT 0x00でソフトウエア割り込みを起こしたところ正常に動作しました。
|
346
|
+
|
347
|
+
|
348
|
+
|
349
|
+
なので、・・・
|
350
|
+
|
351
|
+
void(* a)();
|
352
|
+
|
353
|
+
a = aaa;
|
354
|
+
|
355
|
+
_set_gate(0x8400,14,0,&a,0x08);
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
このようにしてaaa関数へのゲートディスクリプタを作成してINT 0x00で呼び出したのですが
|
360
|
+
|
361
|
+
エラーこそ起こらないものの画面に何も表示されず
|
362
|
+
|
363
|
+
期待通りの動作になりません。
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
0x8600に配置したループ処理が呼べたことから
|
368
|
+
|
369
|
+
割り込み処理ルーチンのアドレス設定は問題なくできているものと思われます。(たぶん)
|
370
|
+
|
371
|
+
|
372
|
+
|
373
|
+
なので、どちらかと言えば
|
374
|
+
|
375
|
+
aaa関数 あるいは aaa関数内で呼ばれているprotect_puts(文字表示関数)のほうに問題があると思うのですが・・・
|
376
|
+
|
377
|
+
|
378
|
+
|
379
|
+
何がいけないんでしょうか?
|
380
|
+
|
381
|
+
アセンブリ言語でいうところのret命令みたいのが必要なのでしょうか?
|
382
|
+
|
383
|
+
(いや、それだったらエラーになるはずだが・・・)
|
1
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -447,3 +447,219 @@
|
|
447
447
|
|
448
448
|
|
449
449
|
どこが間違えているのでしょうか?
|
450
|
+
|
451
|
+
|
452
|
+
|
453
|
+
### 自分でIDT登録関数を作ってみた
|
454
|
+
|
455
|
+
ゲートのフォーマット
|
456
|
+
|
457
|
+
[リンク内容](http://softwaretechnique.jp/OS_Development/kernel_development02.html)
|
458
|
+
|
459
|
+
```c
|
460
|
+
|
461
|
+
void set_intr_gate()
|
462
|
+
|
463
|
+
{
|
464
|
+
|
465
|
+
int b = 割り込み処理ルーチン先頭アドレス;
|
466
|
+
|
467
|
+
__asm__(
|
468
|
+
|
469
|
+
/* IDT再設定 */
|
470
|
+
|
471
|
+
"lidt IDTR\n\t"
|
472
|
+
|
473
|
+
|
474
|
+
|
475
|
+
|
476
|
+
|
477
|
+
|
478
|
+
|
479
|
+
"mov $IDTアドレス + 0,%%ebx\n\t" /* 下位16bitオフセット */
|
480
|
+
|
481
|
+
"mov %1,%%eax\n\t"
|
482
|
+
|
483
|
+
"mov %%ax,(%%ebx)\n\t"
|
484
|
+
|
485
|
+
|
486
|
+
|
487
|
+
"mov $IDTアドレス + 0x10,%%ebx\n\t" /* セグメントセレクター */
|
488
|
+
|
489
|
+
"mov $0x08,%%eax\n\t"
|
490
|
+
|
491
|
+
"mov %%ax,(%%ebx)\n\t"
|
492
|
+
|
493
|
+
|
494
|
+
|
495
|
+
"mov $IDTアドレス + 0x20,%%ebx\n\t" /* DPLとか・・・ */
|
496
|
+
|
497
|
+
"mov $0b11110111100000000,%%eax\n\t"
|
498
|
+
|
499
|
+
"mov %%ax,(%%ebx)\n\t"
|
500
|
+
|
501
|
+
|
502
|
+
|
503
|
+
"mov $IDTアドレス + 0x30,%%ebx\n\t" /* 上位16bitオフセット */
|
504
|
+
|
505
|
+
"mov %1,%%eax\n\t"
|
506
|
+
|
507
|
+
"shr $16,%%eax\n\t"
|
508
|
+
|
509
|
+
"mov %%ax,(%%ebx)\n\t"
|
510
|
+
|
511
|
+
|
512
|
+
|
513
|
+
|
514
|
+
|
515
|
+
|
516
|
+
|
517
|
+
"jmp .end\n\t"
|
518
|
+
|
519
|
+
"IDTR:\n\t"
|
520
|
+
|
521
|
+
".word 0xIDTサイズ\n\t"
|
522
|
+
|
523
|
+
".word 0x0000\n\t"
|
524
|
+
|
525
|
+
".word 0xIDTアドレス\n\t"
|
526
|
+
|
527
|
+
".end:\n\t"
|
528
|
+
|
529
|
+
:"=m" (b)
|
530
|
+
|
531
|
+
:"m" (b)
|
532
|
+
|
533
|
+
);
|
534
|
+
|
535
|
+
}
|
536
|
+
|
537
|
+
|
538
|
+
|
539
|
+
```
|
540
|
+
|
541
|
+
割り込み処理ルーチン
|
542
|
+
|
543
|
+
```s
|
544
|
+
|
545
|
+
times (512 * 10) - ($ - $$) db 0x00
|
546
|
+
|
547
|
+
jmp $
|
548
|
+
|
549
|
+
```
|
550
|
+
|
551
|
+
10セクター目に jmp $ を設置しました。これをソフトウエア割り込みで呼び出せるようにしたいです。
|
552
|
+
|
553
|
+
(これで正しく動くかはわからないが・・・)
|
554
|
+
|
555
|
+
|
556
|
+
|
557
|
+
10セクターなので・・・
|
558
|
+
|
559
|
+
0x200(512)× 0x0A(10) + 0x7C00(ロードされるアドレス) = 0x9000
|
560
|
+
|
561
|
+
|
562
|
+
|
563
|
+
IDT
|
564
|
+
|
565
|
+
"lidt IDTR\n\t"
|
566
|
+
|
567
|
+
"IDTR:\n\t"
|
568
|
+
|
569
|
+
".word 0x0200\n\t"
|
570
|
+
|
571
|
+
".word 0x8400\n\t"
|
572
|
+
|
573
|
+
|
574
|
+
|
575
|
+
より、0x8400からIDTを開始させているつもりです。
|
576
|
+
|
577
|
+
|
578
|
+
|
579
|
+
```c
|
580
|
+
|
581
|
+
void set_intr_gate()
|
582
|
+
|
583
|
+
{
|
584
|
+
|
585
|
+
void(* a)();
|
586
|
+
|
587
|
+
a = aaa;
|
588
|
+
|
589
|
+
int b = 0x9000;
|
590
|
+
|
591
|
+
/* int b = 0x9C00; */
|
592
|
+
|
593
|
+
__asm__(
|
594
|
+
|
595
|
+
/* IDT再設定 */
|
596
|
+
|
597
|
+
"lidt IDTR\n\t"
|
598
|
+
|
599
|
+
|
600
|
+
|
601
|
+
/* ゲートディスクリプタを作成 */
|
602
|
+
|
603
|
+
|
604
|
+
|
605
|
+
"mov $0x8400,%%ebx\n\t" /* 下位16bitオフセット */
|
606
|
+
|
607
|
+
"mov %1,%%eax\n\t"
|
608
|
+
|
609
|
+
"mov %%ax,(%%ebx)\n\t"
|
610
|
+
|
611
|
+
|
612
|
+
|
613
|
+
"mov $0x8410,%%ebx\n\t" /* セグメントセレクター */
|
614
|
+
|
615
|
+
"mov $0x08,%%eax\n\t"
|
616
|
+
|
617
|
+
"mov %%ax,(%%ebx)\n\t"
|
618
|
+
|
619
|
+
|
620
|
+
|
621
|
+
"mov $0x8420,%%ebx\n\t" /* DPLとか・・・ */
|
622
|
+
|
623
|
+
"mov $0b11110111100000000,%%eax\n\t"
|
624
|
+
|
625
|
+
"mov %%ax,(%%ebx)\n\t"
|
626
|
+
|
627
|
+
|
628
|
+
|
629
|
+
"mov $0x8430,%%ebx\n\t" /* 上位16bitオフセット */
|
630
|
+
|
631
|
+
"mov %1,%%eax\n\t"
|
632
|
+
|
633
|
+
"shr $16,%%eax\n\t"
|
634
|
+
|
635
|
+
"mov %%ax,(%%ebx)\n\t"
|
636
|
+
|
637
|
+
|
638
|
+
|
639
|
+
|
640
|
+
|
641
|
+
|
642
|
+
|
643
|
+
"jmp .end\n\t"
|
644
|
+
|
645
|
+
"IDTR:"
|
646
|
+
|
647
|
+
".word 0x0200\n\t"
|
648
|
+
|
649
|
+
".word 0x0000\n\t"
|
650
|
+
|
651
|
+
".word 0x8400\n\t"
|
652
|
+
|
653
|
+
".end:\n\t"
|
654
|
+
|
655
|
+
:"=m" (b)
|
656
|
+
|
657
|
+
:"m" (b)
|
658
|
+
|
659
|
+
);
|
660
|
+
|
661
|
+
```
|
662
|
+
|
663
|
+
実行してみるものもまだエラーになります。
|
664
|
+
|
665
|
+
IDT開始アドレスの定義がおかしいのか、それとも割り込み処理ルーチンアドレスの設定が間違えているのか・・・。
|