冲突类型和以前的功能声明?

时间:2012-04-17 22:21:47

标签: c

使用make来编译操作系统时,我有一个奇怪的错误来自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

有问题的功能是随后的功能。我没有包含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中:     ....     extern 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);
}

2 个答案:

答案 0 :(得分: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文件中的声明以匹配。

它真的很臭,但我之前在分布式源代码中遇到过这样的问题(特别是在学校......)。

。不确定甚至不能编译的代码如何能够像这样进入野外。但它确实发生了。

答案 1 :(得分:2)

功能签名不匹配:

.h档案中的声明:

void page_fault(registers_t *regs)

.c文件中的定义:

void page_fault(registers_t regs)

更正标头文件中的签名以匹配.c文件中的签名(即从*移除paging.h)。