I decided to write a small OS, because I wonder how they work. I found a tutorial on wiki.osdev.org, everything seemed to be fine, but then I started writing the memory manager myself. I compile C code and compile with gcc (i686-elf-gcc, Mac cross compiler), assembler with NASM. Here is an excerpt of the code for which you swear:

void init_heap() { extern uint16_t kernel_heap; uint16_t *ge = &kernel_heap; for (int i = 0; i <= 3; i++) { pg[i].frbytes = 16380; pg[i].offset = ge + (PAGE_SIZE * i); //PAGE_SIZE = 16384, pg - массив структур page /* typedef struct { uint16_t frbytes; uint16_t offset; } */ } 

... (there is more code, then the parenthesis is closed) The variable kernel_heap is declared in another file, heap.asm:

 section .heap: kernel_heap: resb 65536 

There are no errors during the compilation, but when linking it pops up: arch / i386 / memory.o: In function init_heap': $HOME/Golub/kernel/arch/i386/memory.c:96: undefined reference to kernel_heap' (this is exactly after layout) In this case, if you do not perform any operations with ge, then the OS starts up quietly. Please help, because I need to offset each element of the array pg to store the address (variable address + page size * index)

    1 answer 1

    C ... NASM

    1. For a name to be available outside the heap.asm module, it must be declared as global
    2. C expects external names to begin with an underscore. In the C source itself, these underscores are not present (the compiler converts the names automatically), but in the case of the assembler, they must be added manually.

    Therefore:

     global _kernel_heap _kernel_heap: 
    • Please try to write more detailed answers. I am sure the author of the question would be grateful for your expert comment. - Nicolas Chabanovsky