0

こんにちは、カーネル バージョン 2.4.20 から新しいカーネルをコンパイルしようとしています。さらに、構造の定義 (リンクされたリストとリスト構造で使用されるノードを定義するためのもの) と、新しいシステムコール ファイルで定義された 2 つの関数プロトタイプを含むヘッダー ファイルがありますsample.csched.cただし、リストをグローバルに定義し、関数内で割り当てを行おうとするとsched_init()、新しいカーネル バージョンが開きません。始める前に立ち往生します。ここで、ヘッダー ファイルとシステム コール ファイルを確認できます。

/* project_header.h */

#ifndef __LINUX_PROJECT_HEADER_H

#define __LINUX_PROJECT_HEADER_H

#include <linux/linkage.h>
#include <linux/vmalloc.h>

#endif

typedef struct node{

        struct node* next;
    struct node* prev;
        long project_pid;
    long project_ticket_number;

}PROJECT_NODE;

typedef struct{

        PROJECT_NODE* head;
        PROJECT_NODE* tail;
        int list_size;

}PROJECT_LIST;

PROJECT_LIST* project_init_list(void);
void project_add_node(PROJECT_LIST*, long);

sampleこれは私が実装した私のシステムコールです。ご覧のとおり、ここで関数を定義する必要があり、プロトタイプは と のproject_header.h2つの system_call ファイルによって呼び出されfork.cますsched.c

/* sample.c */

#include <linux/sample.h>
#include <linux/project_header.h>

long int maximum_ticket_number=0;
extern PROJECT_LIST* project_list;

PROJECT_LIST* project_init_list(void){

    PROJECT_LIST* list = vmalloc(sizeof(*list));

        list->list_size=0;
        list->head = NULL;
        list->tail = NULL;

    return list;
}

void project_add_node(PROJECT_LIST* list, long id){

     PROJECT_NODE* pnew;

     pnew = vmalloc(sizeof(*pnew));

     pnew->project_pid=id;

    maximum_ticket_number++;
    pnew->project_ticket_number=maximum_ticket_number;

    if(list->list_size==0){ // Assume list is empty

                   list->head = pnew;
                   list->tail = pnew;

                   list->list_size++;
    }
    else {

         list->tail->next = pnew;
         pnew->prev = list->tail;
         list->tail = pnew;

         list->list_size++;
         }

}

asmlinkage void sys_sample(void){ //System call does print the inital list size

        printk("LIST->SIZE = %d\n", project_list->list_size);

    return;
}

これが追加された部分ですsched.c

/* sched.c */
.
.

#include <linux/project_header.h>
#include <linux/sample.h>

PROJECT_LIST* project_list; // Create a list globally

extern PROJECT_LIST* project_init_list(void); // Provide to call project_init_list function which returns a list properly

.
.

void __init sched_init(void){

.
.
project_list = vmalloc(sizeof(*project_list)); //Allocate space and initialize the variables of main list
.
.

これは、カーネルが開始される前の私の現在の状況のスナップショットです

ここに画像の説明を入力

問題は機能にあると確信していますが、sched_init()見つけることができません。とにかく助けてくれてありがとう。

4

1 に答える 1

0

これは、与えられた情報で答えられる質問ではないため、実際には答えではありません。しかし、それは「カーネルが起動しない理由を見つける方法と、カーネルが起動する方法についてのちょっとしたガイダンス」です。

printk() は、カーネル外部の printf() に対応するカーネル関数です。到達していると思われるポイントと、失敗する可能性があると思われる場所にそれを追加します。たとえば、「myptr = vmalloc(...);」がある場合は、

明らかに、カーネル自体が開始されておらず、printk が利用できない可能性があるほど早い場合は、シリアルポートへの out を使用してデバッグする必要があります -

  mov $0x3fc, dx
  mov $65, al
  out al, dx

'A' (ASCII コード 65) をシリアル ポートに出力します。一度に約 16 文字を超えて打ち出さないでください。それらは 9600 bps 程度でしか出てきません。

ところで、保護モードでないカーネルの唯一の部分は、数十個程度の命令です。

ただし、仮想メモリの処理はすぐには開始されず、実際には、スケジューリング後および「kswapper」プロセスが開始されるまで機能しないことに気付く場合があります。つまり、スケジューラで vmalloc を使用することはできません。これはよく知っている Linux カーネルの一部ではないため、確かではありませんが、代わりに低レベルのカーネル機能である kmalloc を調べる価値があるかもしれません。これらは正確な置換ではないことに注意してください。そのため、パラメーターとその意味、および翻訳方法を確認する必要があります。カーネルで vmalloc() を使用したことがないと思います。使用する正しい関数であると確信していますか?

于 2012-12-31T08:03:22.807 に答える