2012-04-17 2 views
0

При использовании make для компиляции ОС у меня есть странная ошибка, из которой я не понимаю.Конфликтующие типы и предыдущее объявление функции?

от макияжа:

source/paging.c:179:6: error: conflicting types for ‘page_fault’ 
headers/paging.h:68:6: note: previous declaration of ‘page_fault’ was here 
make: *** [obj/paging.o] Error 1 

Функция (ы) в вопросе являются те, которые следуют. Я не включил весь файл paging.c, поскольку он очень большой, то же самое относится к paging.h tbh, но если вы хотите увидеть файл заголовка, я опубликую остальное.

paging.c:

.... 
.... 
void page_fault(registers_t regs) 
{ 
// A page fault has occurred. 
// The faulting address is stored in the CR2 register. 
u32int faulting_address; 
asm volatile("mov %%cr2, %0" : "=r" (faulting_address)); 

// The error code gives us details of what happened. 
int present = !(regs.err_code & 0x1); // Page not present 
int rw = regs.err_code & 0x2;   // Write operation? 
int us = regs.err_code & 0x4;   // Processor was in user-mode? 
int reserved = regs.err_code & 0x8;  // Overwritten CPU-reserved bits of page entry? 
int id = regs.err_code & 0x10;   // Caused by an instruction fetch? 

// Output an error message. 
monitor_write("Page fault! ("); 
if (present) {monitor_write("present ");} 
if (rw) {monitor_write("read-only ");} 
if (us) {monitor_write("user-mode ");} 
if (reserved) {monitor_write("reserved ");} 
monitor_write(") at 0x"); 
monitor_write_hex(faulting_address); 
monitor_write("\n"); 
PANIC("Page fault"); 
} 

paging.h:

.... 
.... 
void page_fault(registers_t *regs); 
.... 
.... 

ПРИМЕЧАНИЕ: Это из учебника (так оно должно работать, но я пришел в проблему с прилагаемым исходный код до того, когда одна функция не была написана правильно).

Любая идея, почему make жалуется?

Спасибо.

делают ошибки без *:

obj/interrupt.o: In function `isr_common_stub': 
asem/interrupt.s:(.text+0x1c9): undefined reference to `isr_handler' 
obj/interrupt.o: In function `irq_common_stub': 
asem/interrupt.s:(.text+0x1ee): undefined reference to `irq_handler' 
obj/main.o: In function `main': 
main.c:(.text+0x6e): undefined reference to `placement_address' 
obj/descriptor_tables.o: In function `init_descriptor_tables': 
descriptor_tables.c:(.text+0x23): undefined reference to `interrupt_handlers' 
obj/timer.o: In function `init_timer': 
timer.c:(.text+0x30): undefined reference to `register_interrupt_handler' 
obj/paging.o: In function `initialise_paging': 
paging.c:(.text+0x298): undefined reference to `kmalloc' 
paging.c:(.text+0x2cc): undefined reference to `kmalloc_a' 
paging.c:(.text+0x328): undefined reference to `placement_address' 
paging.c:(.text+0x341): undefined reference to `register_interrupt_handler' 
obj/paging.o: In function `get_page': 
paging.c:(.text+0x3da): undefined reference to `kmalloc_ap' 
obj/initrd.o: In function `initialise_initrd': 
initrd.c:(.text+0x1f1): undefined reference to `kmalloc' 
initrd.c:(.text+0x2f5): undefined reference to `kmalloc' 
initrd.c:(.text+0x402): undefined reference to `kmalloc' 
obj/task.o: In function `initialise_tasking': 
task.c:(.text+0x24): undefined reference to `kmalloc' 
task.c:(.text+0x9a): undefined reference to `kmalloc_a' 
obj/task.o: In function `fork': 
task.c:(.text+0x2b3): undefined reference to `clone_directory' 
task.c:(.text+0x2c2): undefined reference to `kmalloc' 
task.c:(.text+0x314): undefined reference to `kmalloc_a' 
obj/syscall.o: In function `initialise_syscalls': 
syscall.c:(.text+0x8b): undefined reference to `register_interrupt_handler' 
make: *** [kern/kernel] Error 1 

interrupt.s:

.... 
; In isr.c 
extern irq_handler 
.... 
.... 
; In isr.c 
extern isr_handler 

main.c: .... ехЬегп u32int placement_address; ....

descriptor_tables.c:

void init_descriptor_tables() 
{ 

// Initialise the global descriptor table. 
init_gdt(); 
// Initialise the interrupt descriptor table. 
init_idt(); 
// Nullify all the interrupt handlers. 
memset(&interrupt_handlers, 0, sizeof(isr_t)*256); 
} 

timer.c:

void init_timer(u32int frequency) 
{ 
// Firstly, register our timer callback. 
register_interrupt_handler(IRQ0, &timer_callback); 

// The value we send to the PIT is the value to divide it's input clock 
// (1193180 Hz) by, to get our required frequency. Important to note is 
// that the divisor must be small enough to fit into 16-bits. 
u32int divisor = 1193180/frequency; 

// Send the command byte. 
outb(0x43, 0x36); 

// Divisor has to be sent byte-wise, so split here into upper/lower bytes. 
u8int l = (u8int)(divisor & 0xFF); 
u8int h = (u8int)((divisor>>8) & 0xFF); 

// Send the frequency divisor. 
outb(0x40, l); 
outb(0x40, h); 
} 

paging.c:

.... 
void initialise_paging() 
{ 
// The size of physical memory. For the moment we 
// assume it is 16MB big. 
u32int mem_end_page = 0x1000000; 

nframes = mem_end_page/0x1000; 
frames = (u32int*)kmalloc(INDEX_FROM_BIT(nframes)); 
memset(frames, 0, INDEX_FROM_BIT(nframes)); 

// Let's make a page directory. 
kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t)); 
current_directory = kernel_directory; 

// We need to identity map (phys addr = virt addr) from 
// 0x0 to the end of used memory, so we can access this 
// transparently, as if paging wasn't enabled. 
// NOTE that we use a while loop here deliberately. 
// inside the loop body we actually change placement_address 
// by calling kmalloc(). A while loop causes this to be 
// computed on-the-fly rather than once at the start. 
int i = 0; 
while (i < placement_address) 
{ 
    // Kernel code is readable but not writeable from userspace. 
    alloc_frame(get_page(i, 1, kernel_directory), 0, 0); 
    i += 0x1000; 
} 
// Before we enable paging, we must register our page fault handler. 
register_interrupt_handler(14, page_fault); 

// Now, enable paging! 
switch_page_directory(kernel_directory); 
} 
+0

Это ошибки компоновщика, некоторые библиотеки или объектные файлы отсутствуют в командной строке. Сама компиляция завершена. –

+0

Очистите и перестройте свой проект. –

+0

@EdS. - Я сделал это со всем, что было предложено: L –

ответ

4

У вас есть две различные подписи для функции с тем же именем. Обратите внимание, что первое объявление принимает registers_t, а второе принимает registers_t*.

/* paging.h */ 
void page_fault(registers_t *regs); 

/* paging.c */ 
void page_fault(registers_t regs) 

Функция подписи в paging.c является правильным за использование переменной regs, поэтому изменить объявление в файле .h, чтобы соответствовать.

Это действительно воняет, но я столкнулся с такими проблемами в распространенном исходном коде (особенно в школе ...). Не уверен, как код, который даже не будет компилироваться, может сделать это в диком, как это, но это происходит.

+0

так что вы говорите, удалите * из paging.h? или добавить его в paging.c? –

+0

Да, измените подпись в 'paging.h', чтобы она соответствовала строке в' paging.c' (т. Е. Удалите '*'). Подпись функции включает в себя ее тип возврата, имя и любые аргументы. Например, это сигнатура функции: 'int some_func (char * c)' –

+0

, которая теперь сделана make, дает мне неопределенную ссылку на почти все функции в paging.c (несмотря на то, что явно дает правильные ссылки) XD –

2

Функция подписи не совпадают:

Декларация в .h файл:

void page_fault(registers_t *regs) 

Определение в .c файле:

void page_fault(registers_t regs) 

Правильная подпись в файле заголовка, чтобы соответствовать одному в файле .c (т.е. удалите * от paging.h).

+0

Выполнение этого дало мне эту ошибку, и это для каждого err_code в этой функции: source/paging.c: 191: 18: error: запрос для члена err_code в чем-то, что не является структурой или соединением –

+0

Удалили ли вы ' 'из файла заголовка' paging.h'? – mizo

+0

Да, я удалил его: L –

Смежные вопросы