2012-04-17 2 views
0

OS를 컴파일하기 위해 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 : .... 통근 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); 
} 

타이머 .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.c에서

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

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

함수 서명

변수 regs의 용도에 따라 올바른, 그래서 일치하도록 .h 파일의 선언을 변경합니다.

정말 악취가 나지만, 분산 된 소스 코드에서 (특히 학교에서 ...) 이런 문제가 발생했습니다. 컴파일하지 않은 코드가 어떻게 이런 식으로 야생으로 만들 수 있는지 확실하지 않지만 일어납니다.

+0

당신의 말은 paging.h에서 *를 제거 하시겠습니까? 또는 paging.c에 추가할까요? –

+0

예, 'paging.h'의 서명을 'paging.c'의 서명과 일치하도록 변경하십시오 (즉,'*'제거). 함수의 서명에는 반환 유형, 이름 및 인수가 포함됩니다. 예를 들어 이것은 다음과 같은 함수 시그니처이다.'int some_func (char * c)' –

+0

이제는 paging.c의 모든 함수에 대한 정의되지 않은 참조를 제공하게된다. (분명히 올바른 참조가 있음에도 불구하고) XD –

2

기능 서명이 일치하지 않습니다 :

void page_fault(registers_t regs) 

올바른 헤더 파일의 서명이 하나와 일치하는 :

void page_fault(registers_t *regs) 

정의 .c 파일 :

선언 파일 .h.c 파일 (예 : *paging.h에서 삭제).

+0

이렇게하면 저에게이 오류가 발생합니다.이 함수의 모든 err_code에 대한 것입니다 : source/paging.c : 191 : 18 : error : 구조체 또는 공용체가 아닌 'err_code'멤버에 대한 요청 –

+0

' ''paging.h' 헤더 파일에서? – mizo

+0

예 제거 : L –