-1

I am trying to make a operating system. I just finished the bootloader, however I am having a problem loading my kernel.

Boot.asm:

section .boot
bits 16
global boot
boot:
    mov ax, 0x2401
    int 0x15

    mov ax, 0x3
    int 0x10

    mov [disk],dl

    mov ah, 0x2    ;read sectors
    mov al, 6      ;sectors to read
    mov ch, 0      ;cylinder idx
    mov dh, 0      ;head idx
    mov cl, 2      ;sector idx
    mov dl, [disk] ;disk idx
    mov bx, copy_target;target pointer
    int 0x13
    cli
    lgdt [gdt_pointer]
    mov eax, cr0
    or eax,0x1
    mov cr0, eax
    mov ax, DATA_SEG
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp CODE_SEG:boot2
gdt_start:
    dq 0x0
gdt_code:
    dw 0xFFFF
    dw 0x0
    db 0x0
    db 10011010b
    db 11001111b
    db 0x0
gdt_data:
    dw 0xFFFF
    dw 0x0
    db 0x0
    db 10010010b
    db 11001111b
    db 0x0
gdt_end:
gdt_pointer:
    dw gdt_end - gdt_start
    dd gdt_start
disk:
    db 0x0
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

times 510 - ($-$$) db 0
dw 0xaa55
copy_target:
bits 32
    hello: db "Hello more than 512 bytes world!!",0
boot2:
    mov esi,hello
    mov ebx,0xb8000
.loop:
    lodsb
    or al,al
    jz halt
    or eax,0x0F00
    mov word [ebx], ax
    add ebx,2
    jmp .loop
halt:
    mov esp,kernel_stack_top
    extern kzos
    call kzos
    cli
    hlt

section .bss
align 4
kernel_stack_bottom: equ $
    resb 16384 ; 16 KB
kernel_stack_top:

kzos.cpp

extern "C" void kzos()
{
    const short color = 0x0F00;
    const char* hello = "Kernel test!";
    short* vga = (short*)0xb8000;
    for (int i = 0; i<16;++i)
        vga[i+80] = color | hello[i];
}

The error I am getting is with " extern kzos" the error reads "boot.asm:77: error: binary output format does not support external references"

I tried adding " extern kzos.cpp " but then I get "boot.asm:77: error: symbol `kmain' undefined" if I add ".cpp" to the call function I get "boot4.asm:77: error: binary output format does not support external references"

I am using Nasm to compile to bin and qemu to run it.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
ZTECH
  • 11
  • 1
  • 1
    Please describe your tool chain. What assembler, what compiler, etc. – Yakk - Adam Nevraumont Aug 08 '21 at 20:45
  • 1
    You did not show how you build things, but if you don't link them together then you need to find a way to supply the address of `kzos` yourself. E.g. you can place a pointer or a jump at the start of the kernel. – Jester Aug 08 '21 at 20:47
  • 1
    Does this answer your question? [nasm : error : binary output format does not support external references](https://stackoverflow.com/questions/60174684/nasm-error-binary-output-format-does-not-support-external-references) – Lala5th Aug 08 '21 at 20:49
  • [How to make the kernel for my bootloader?](https://stackoverflow.com/q/33603842) has a working example of calling C in protected mode, from a bootloader that starts in real mode. You didn't show exactly what commands you're trying to run that generate these link errors. – Peter Cordes Aug 08 '21 at 21:03
  • Im running linux mint and nasm and qemu. The command I am using is: nasm -fbin boot.asm -o boot.bin. – ZTECH Aug 08 '21 at 21:08
  • As mentioned in the other post, the binary format does not have a symbol table. From what I've seen you have to compile into an object file normally (elf) and then use the linker to generate a raw binary – Lala5th Aug 08 '21 at 21:11

2 Answers2

2

I just finished the bootloader, ...

No you didn't. At least half of a boot loader's code exists to handle errors that "shouldn't" happen (things like checking if the BIOS failed to enable A20, or if the BIOS says there was a problem reading data from disk) and handling those cases somehow - at a minimum, by providing the user information that can help them fix the problem (and determine if it's faulty hardware or a problem with the way the OS was installed or ...), so the user isn't stuck wondering why their entire computer is unusable (and so that you're not stuck with a bug report saying "doesn't boot" with no useful information either).

how do I load my kernel from my bootloader?

Your choices for finding where the kernel is (its location on the disk and its size) are:

a) Put the kernel in some kind of normal file system, and have the boot loader support that file system (e.g. find the right directory entry and get location of file's data from the file's directory entry). Note that this is complicated (e.g. you'll have a lot of error handling, in case the file system's structures are corrupted, etc)

b) Put the kernel in some kind of purpose designed file system or in some kind of purpose designed "special/reserved area" of a normal file system. This could be as simple as a table of "offset and length" structures stored in the first sector, where kernel's file is always the first entry in that table.

c) Include the kernel's binary directly into the boot loader using something like the incbin directive in NASM. In this case you can use labels to determine the size of the kernel's file, like:

kernel_start:
    incbin 'kernel.bin'
kernel_end:

In this case you can determine where the kernel is on disk from where the boot loader was on disk, and calculate how many sectors it is (e.g. (kernel_end - kernel_start + SECTOR_SIZE-1)/SECTOR_SIZE). Of course this is horribly inflexible (e.g. you can't easily update the kernel without assembling and then reinstalling the boot loader).

Once you've determined the location and size of the kernel on disk; you need to load it into memory somewhere. Note that this can depend on what kind of executable file format you chose to use for the kernel; and could involve loading the executable file's headers and parsing them to figure out which parts of the file should go where in memory (and setting up things like ".bss" that aren't in the file).

Brendan
  • 35,656
  • 2
  • 39
  • 66
0

the output format is bin, flat format, that is

it does not support rellocations

thus call kzos's location/address is lost once the code is rendered
any linking utility will fail locating call kzos' in order
to link it to the new address of extern "C" void kzos() from kzos.cpp

Errorist
  • 224
  • 2
  • 6