简体   繁体   English

类型和先前的函数声明冲突?

[英]Conflicting types and previous declaration of function?

While using make to compile an OS I've got a weird error from make that I don't understand. 使用make编译操作系统时,我从make中收到一个奇怪的错误,我不明白。

from make: 来自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

The function(s) in question are the ones that follow. 有问题的功能如下。 I haven't included the whole file of paging.c as it is very big, same goes for paging.h tbh, but if you want to see the header file I will post the rest. 我没有包含整个page.c文件,因为它很大,pageing.h tbh也是如此,但是如果您想查看头文件,我将把其余文件发布。

paging.c: page.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: pages.h:

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

NOTE: This is from a tutorial ( so it should be working, but I have come into a problem with the provided source code before where one function wasn't spelt properly ). 注意:这是来自教程(因此应该可以正常工作,但是在没有正确拼写一个函数之前,我遇到了所提供的源代码的问题)。

Any idea's why make is complaining? 知道为什么make会抱怨吗?

Thanks. 谢谢。

make errors without *: 错误不带*:

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: .... extern u32int placement_address; main.c:.... extern u32int placement_address; .... ....

descriptor_tables.c: 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: 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: page.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);
}

You have two differing signatures for a function with the same name. 具有相同名称的函数有两个不同的签名。 Note that the first declaration takes a registers_t , but the second takes a registers_t* . 请注意,第一个声明采用registers_t ,而第二个声明采用registers_t*

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

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

The function signature in paging.c is correct per the usage of the variable regs , so change the declaration in the .h file to match. 按变量regs的用法, paging.c的函数签名是正确的,因此请更改.h文件中的声明以使其匹配。

It really stinks, but I have run into problems like this in distributed source code before (especially in school...). 它确实很臭,但是以前在分布式源代码中(尤其是在学校里……)遇到了这样的问题。 Not sure how code that won't even compile can make it out into the wild like this, but it happens. 不确定甚至无法编译的代码如何将其变成这样,但它确实发生了。

The function signatures don't match: 函数签名不匹配:

Declaration in .h file: .h文件中的声明:

void page_fault(registers_t *regs)

Definition in .c file: .c文件中的定义:

void page_fault(registers_t regs)

Correct the signature in header file to match the one in the .c file (ie remove the * from paging.h ). 更正头文件中的签名以匹配.c文件中的签名(即,从paging.h删除* )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM