簡體   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