繁体   English   中英

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

[英]Conflicting types and previous declaration of function?

使用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

有问题的功能如下。 我没有包含整个page.c文件,因为它很大,pageing.h tbh也是如此,但是如果您想查看头文件,我将把其余文件发布。

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");
}

pages.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

中断:

....
; 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);
}

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);
}

具有相同名称的函数有两个不同的签名。 请注意,第一个声明采用registers_t ,而第二个声明采用registers_t*

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

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

按变量regs的用法, paging.c的函数签名是正确的,因此请更改.h文件中的声明以使其匹配。

它确实很臭,但是以前在分布式源代码中(尤其是在学校里……)遇到了这样的问题。 不确定甚至无法编译的代码如何将其变成这样,但它确实发生了。

函数签名不匹配:

.h文件中的声明:

void page_fault(registers_t *regs)

.c文件中的定义:

void page_fault(registers_t regs)

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

暂无
暂无

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

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