English 中文(简体)
不能说是真正的模式 boot(NASM+海湾合作委员会工具链)
原标题:Cannot call real mode C function from bootloader (NASM + GCC toolchain)

我正试图写一下我自己的协调人,并一直有一些问题使我的boot子和我的ker子(很快会写在C)。

我有以下法典......

rc

; Allows our code to be run in real mode.
BITS 16
extern kmain

section .text
global _start
_start:
        jmp Start

; Moves the cursor to row dl, col dh.
MoveCursor:
    mov ah, 2
    mov bh, 0
    int 10h
    ret

; Prints the character in al to the screen.
PrintChar:
    mov ah, 10
    mov bh, 0
    mov cx, 1
    int 10h
    ret

; Set cursor position to 0, 0.
ResetCursor:
    mov dh, 0
    mov dl, 0
    call MoveCursor
    ret

Start:
        call ResetCursor

; Clears the screen before we print the boot message.
; QEMU has a bunch of crap on the screen when booting.
Clear:
        mov al,    
        call PrintChar

        inc dl
        call MoveCursor

        cmp dl, 80
        jne Clear

        mov dl, 0
        inc dh
        call MoveCursor

        cmp dh, 25
        jne Clear

; Begin printing the boot message. 
Msg:    call ResetCursor
        mov si, BootMessage

NextChar:
        lodsb
        call PrintChar

        inc dl
        call MoveCursor

        cmp si, End
        jne NextChar 

call kmain

BootMessage: db "Booting..."
End:

; Zerofill up to 510 bytes
times 510 - ($ - $$)  db 0

; Boot Sector signature
dw 0AA55h

src/god.c

asm(".code16gcc");

// JASOS kernel entry point.
void kmain()
{
    asm(     "movb $0, %dl;"
             "inc %dh;"
             "movb $2, %ah;"
             "movb $0, %bh;"
             "int $0x10;"
             "movb $ a , %al;"
             "movb $10, %ah;"
             "movw $1, %cx;"
             "int $0x10;"   );

    while (1);
}

以及最后......

bootloader: rc
    nasm -f elf32 rc -o build/bootloader.o

god: src/god.c
    i686-elf-gcc -c src/god.c -o build/god.o -ffreestanding

os: bootloader god
    i686-elf-ld -Ttext=0x7c00 --oformat binary build/bootloader.o build/god.o -o bin/jasos.bin

时装箱相当简单。 它只是从“Booting. 和(对)重荷公里以外。 然而,在画面印本后没有发生。

在<代码>kmain时,我仍然处于正轨。 因此,我并不期望失败,因为我无法接触我在线会议中断的BIOS。 如果我错的话,我就错了。

最佳回答

我不建议海合会制定16条轨道守则。 海湾合作委员会的替代方案可以是:IA16-GCC项目,该项目是正在进行的工作,是实验性的。

由于需要在线集会,很难让海合会通过适当的实时守则。 如果你希望避免出现微妙的弊端,特别是当能够优化时,海湾合作委员会的内线集会就难以正确。 可在<>上填写。 我对此表示强烈反对。

页: 1 书刊只读出一个部门。 您的<代码>jmp kain 结束了对nel子如果实际上被装上记忆,那儿的记忆就会跳跃,但是,它被装上了,因此无法按预期开展工作。 http://www.ctyme.com/intr/rb-0607.htm

您的邮资库适当建立了分部登记册。 由于你正在使用海湾合作委员会,它期望CS=DS=ES=SS。 由于我们需要把数据输入记忆中,我们需要把 st放在安全的地方。 煤油将装上0x0000:0x7e00,这样我们就可以把 st放在0x0000:0x7c00的boot子下,在那里他们赢得了 t。 您需要用CLD。 在此之前,要求海湾合作委员会这样做。 其中许多问题载于我的。 我的另一份Stackoverflowwer

我们需要一份链接稿,以妥善记载记忆中的东西,并确保从一开始就向真实的C切入点kmain发出指示。 我们还需要适当取消黑海经合组织科,因为海合会期望这样做。 联系人文字用于确定BASS部分的开始和结束。 <代码>0_bs 记到0x00。

<代码>Makefile可清理出一条轨道,以便于将来添加代码。 I ve amended the Code, so the Object file have based in the srcDirectory. 这简化了处理程序。

When the real-mode code support was introduced and support added to GNU assembler it was enabled in GCC by using asm (".code16gcc");. For quite some time now GCC has supported the -m16 option that does the same thing. With -m16 you don t need to add the .code16gcc directive to the top of all the files.

我的斜体修改了在屏幕上打印<条码>a的您的在线组件。 仅仅因为我没有改动,就意味着它没有问题。 由于登记被打上了布局,而编辑们则被告知,当优化时,登记册可能会导致奇怪的 b。 答复的第二部分表明,有一个机制,利用BIOS印刷特征,并通过适当的在线集会向青少年进行扼杀。

我建议编辑备选办法<代码>-Os -mregparm=3 -fomit-frame-pointer,以便优化空间。

<>:>

CROSSPRE=i686-elf-
CC=$(CROSSPRE)gcc
LD=$(CROSSPRE)ld
OBJCOPY=$(CROSSPRE)objcopy
DD=dd
NASM=nasm

DIR_SRC=src
DIR_BIN=bin
DIR_BUILD=build

KERNEL_NAME=jasos
KERNEL_BIN=$(DIR_BIN)/$(KERNEL_NAME).bin
KERNEL_ELF=$(DIR_BIN)/$(KERNEL_NAME).elf
BOOTLOADER_BIN=$(DIR_BIN)/bootloader.bin
BOOTLOADER_ASM=$(DIR_SRC)/bootloader.asm
DISK_IMG=$(DIR_BUILD)/disk.img

CFLAGS=-g -fno-PIE -static -std=gnu99 -m16 -Os -mregparm=3 
    -fomit-frame-pointer -nostdlib -ffreestanding -Wall -Wextra
LDFLAGS=-melf_i386

# List all object files here
OBJS=$(DIR_SRC)/god.o

.PHONY: all clean

all: $(DISK_IMG)

$(BOOTLOADER_BIN): $(BOOTLOADER_ASM)
        $(NASM) -f bin $< -o $@

%.o: %.c
        $(CC) -c $(CFLAGS) $< -o $@

$(KERNEL_ELF): $(OBJS)
        $(LD) $(LDFLAGS) -Tlink.ld $^ -o $@

$(KERNEL_BIN): $(KERNEL_ELF)
        $(OBJCOPY) -O binary $< $@

$(DISK_IMG): $(KERNEL_BIN) $(BOOTLOADER_BIN)
        $(DD) if=/dev/zero of=$@ bs=1024 count=1440
        $(DD) if=$(BOOTLOADER_BIN) of=$@ conv=notrunc
        $(DD) if=$(KERNEL_BIN) of=$@ conv=notrunc seek=1

clean:
        rm -f $(DIR_BIN)/*
        rm -f $(DIR_BUILD)/*
        rm -f $(DIR_SRC)/*.o

link.ld:

OUTPUT_FORMAT("elf32-i386");
ENTRY(kmain);
SECTIONS
{
    . = 0x7E00;

    .text.main : SUBALIGN(0) {
        *(.text.bootstrap);
        *(.text.*);
    }

    .data.main : SUBALIGN(4) {
        *(.data);
        *(.rodata*);
    }

    .bss : SUBALIGN(4) {
        __bss_start = .;
        *(.COMMON);
        *(.bss)
    }
    . = ALIGN(4);
    __bss_end = .;

    __bss_sizel = ((__bss_end)-(__bss_start))>>2;
    __bss_sizeb = ((__bss_end)-(__bss_start));

    /DISCARD/ : {
        *(.eh_frame);
        *(.comment);
    }
}

<>strong>src/god.c:

#include <stdint.h>

/* The linker script ensures .text.bootstrap code appears first.
 * The code simply jumps to our real entrypoint kmain */

asm (".pushsection .text.bootstrap
	"
     "jmp kmain
	"
     ".popsection");

extern uintptr_t __bss_start[];
extern uintptr_t __bss_end[];

/* Zero the BSS section */
static inline void zero_bss()
{
    uint32_t *memloc = __bss_start;

    while (memloc < __bss_end)
        *memloc++ = 0;
}

/* JASOS kernel C entrypoint */
void kmain()
{
    /* We need to zero out the BSS section */
    zero_bss();

    asm (
        "movb $0, %dl;"
        "inc %dh;"
        "movb $2, %ah;"
        "movb $0, %bh;"
        "int $0x10;"
        "movb $ a , %al;"
        "movb $10, %ah;"
        "movw $1, %cx;"
        "int $0x10;"
    );

    return;
}

<>strong>src/roomloader.asm:

; Allows our code to be run in real mode.
BITS 16
ORG 0x7c00

_start:
    xor ax, ax                 ; DS=ES=0
    mov ds, ax
    mov es, ax
    mov ss, ax                 ; SS:SP=0x0000:0x7c00
    mov sp, 0x7c00
    cld                        ; Direction flag = 0 (forward movement)
                               ; Needed by code generated by GCC

    ; Read 17 sectors starting from CHS=(0,0,2) to 0x0000:0x7e00
    ; 17 * 512 = 8704 bytes (good enough to start with)
    mov bx, 0x7e00             ; ES:BX (0x0000:0x7e00) is memory right after bootloader
    mov ax, 2<<8 | 17          ; AH=2 Disk Read, AL=17 sectors to read
    mov cx, 0<<8 | 2           ; CH=Cylinder=0, CL=Sector=2
    mov dh, 0                  ; DH=Head=0
    int 0x13                   ; Do BIOS disk read

    jmp 0x0000:Start           ; Jump to start set CS=0

; Moves the cursor to row dl, col dh.
MoveCursor:
    mov ah, 2
    mov bh, 0
    int 10h
    ret

; Prints the character in al to the screen.
PrintChar:
    mov ah, 10
    mov bh, 0
    mov cx, 1
    int 10h
    ret

; Set cursor position to 0, 0.
ResetCursor:
    mov dh, 0
    mov dl, 0
    call MoveCursor
    ret

Start:

    call ResetCursor

; Clears the screen before we print the boot message.
; QEMU has a bunch of crap on the screen when booting.
Clear:
    mov al,    
    call PrintChar

    inc dl
    call MoveCursor

    cmp dl, 80
    jne Clear

    mov dl, 0
    inc dh
    call MoveCursor

    cmp dh, 25
    jne Clear

; Begin printing the boot message.
Msg:
    call ResetCursor
    mov si, BootMessage

NextChar:
    lodsb
    call PrintChar

    inc dl
    call MoveCursor

    cmp si, End
    jne NextChar

    call dword 0x7e00          ; Because GCC generates code with stack
                               ; related calls that are 32-bits wide we
                               ; need to specify `DWORD`. If we don t, when
                               ; kmain does a `RET` it won t properly return
                               ; to the code below.

    ; Infinite ending loop when kmain returns
    cli
.endloop:
    hlt
    jmp .endloop

BootMessage: db "Booting..."
End:

; Zerofill up to 510 bytes
times 510 - ($ - $$)  db 0

; Boot Sector signature
dw 0AA55h

创建了1.44MiB floppy磁盘图像,称为build/disk.img。 它可以在QEMU进行指挥,如:

qemu-system-i386 -fda build/disk.img

预期产出应类似于:

enter image description here


Proper use of Inline Assembly to Write a String Using the BIOS

更复杂的法典文本: 下表列出了海合会扩展在线组群。 答案并不是要讨论海合会延展的在线组装使用,但网上有rel=“noreferer”。 应当指出,there是许多不好的建议、文件、辅导和抽样守则,其中存在问题,这些人员可能根本不了解这个问题。 <<>Yousup>

<>:>

CROSSPRE=i686-elf-
CC=$(CROSSPRE)gcc
LD=$(CROSSPRE)ld
OBJCOPY=$(CROSSPRE)objcopy
DD=dd
NASM=nasm

DIR_SRC=src
DIR_BIN=bin
DIR_BUILD=build

KERNEL_NAME=jasos
KERNEL_BIN=$(DIR_BIN)/$(KERNEL_NAME).bin
KERNEL_ELF=$(DIR_BIN)/$(KERNEL_NAME).elf
BOOTLOADER_BIN=$(DIR_BIN)/bootloader.bin
BOOTLOADER_ASM=$(DIR_SRC)/bootloader.asm
DISK_IMG=$(DIR_BUILD)/disk.img

CFLAGS=-g -fno-PIE -static -std=gnu99 -m16 -Os -mregparm=3 
    -fomit-frame-pointer -nostdlib -ffreestanding -Wall -Wextra
LDFLAGS=-melf_i386

# List all object files here
OBJS=$(DIR_SRC)/god.o $(DIR_SRC)/biostty.o

.PHONY: all clean

all: $(DISK_IMG)

$(BOOTLOADER_BIN): $(BOOTLOADER_ASM)
        $(NASM) -f bin $< -o $@

%.o: %.c
        $(CC) -c $(CFLAGS) $< -o $@

$(KERNEL_ELF): $(OBJS)
        $(LD) $(LDFLAGS) -Tlink.ld $^ -o $@

$(KERNEL_BIN): $(KERNEL_ELF)
        $(OBJCOPY) -O binary $< $@

$(DISK_IMG): $(KERNEL_BIN) $(BOOTLOADER_BIN)
        $(DD) if=/dev/zero of=$@ bs=1024 count=1440
        $(DD) if=$(BOOTLOADER_BIN) of=$@ conv=notrunc
        $(DD) if=$(KERNEL_BIN) of=$@ conv=notrunc seek=1

clean:
        rm -f $(DIR_BIN)/*
        rm -f $(DIR_BUILD)/*
        rm -f $(DIR_SRC)/*.o

link.ld:

OUTPUT_FORMAT("elf32-i386");
ENTRY(kmain);
SECTIONS
{
    . = 0x7E00;

    .text.main : SUBALIGN(0) {
        *(.text.bootstrap);
        *(.text.*);
    }

    .data.main : SUBALIGN(4) {
        *(.data);
        *(.rodata*);
    }

    .bss : SUBALIGN(4) {
        __bss_start = .;
        *(.COMMON);
        *(.bss)
    }
    . = ALIGN(4);
    __bss_end = .;

    __bss_sizel = ((__bss_end)-(__bss_start))>>2;
    __bss_sizeb = ((__bss_end)-(__bss_start));

    /DISCARD/ : {
        *(.eh_frame);
        *(.comment);
    }
}

src/biostty.c:

#include <stdint.h>
#include "../include/biostty.h"

void fastcall
writetty_str (const char *str)
{
    writetty_str_i (str);
}

void fastcall
writetty_char (const uint8_t outchar)
{
    writetty_char_i (outchar);
}

include/x86helper.h:

#ifndef X86HELPER_H
#define X86HELPER_H

#include <stdint.h>

#define STR_TEMP(x) #x
#define STR(x) STR_TEMP(x)

#define TRUE 1
#define FALSE 0
#define NULL (void *)0

/* regparam(3) is a calling convention that passes first
   three parameters via registers instead of on stack.
   1st param = EAX, 2nd param = EDX, 3rd param = ECX */
#define fastcall  __attribute__((regparm(3)))

/* noreturn lets GCC know that a function that it may detect
   won t exit is intentional */
#define noreturn      __attribute__((noreturn))
#define always_inline __attribute__((always_inline))
#define used          __attribute__((used))

/* Define helper x86 function */
static inline void fastcall always_inline x86_hlt(void){
    __asm__ ("hlt
	");
}
static inline void fastcall always_inline x86_cli(void){
    __asm__ ("cli
	");
}
static inline void fastcall always_inline x86_sti(void){
    __asm__ ("sti
	");
}
static inline void fastcall always_inline x86_cld(void){
    __asm__ ("cld
	");
}

/* Infinite loop with hlt to end bootloader code */
static inline void noreturn fastcall haltcpu()
{
    while(1){
        x86_hlt();
    }
}

#endif

include/biostty.h:

#ifndef BIOSTTY_H
#define BIOSTTY_H

#include <stdint.h>
#include "../include/x86helper.h"

/* Functions ending with _i are always inlined */

extern fastcall void
writetty_str (const char *str);

extern fastcall void
writetty_char (const uint8_t outchar);

static inline fastcall always_inline void
writetty_char_i (const uint8_t outchar)
{
   __asm__ ("int $0x10
	"
            :
            : "a"(((uint16_t)0x0e << 8) | outchar),
              "b"(0x0000));
}

static inline fastcall always_inline void
writetty_str_i (const char *str)
{
    /* write characters until we reach nul terminator in str */
    while (*str)
        writetty_char_i (*str++);
}

#endif

<>strong>src/god.c:

#include <stdint.h>
#include "../include/biostty.h"

/* The linker script ensures .text.bootstrap code appears first.
 * The code simply jumps to our real entrypoint kmain */

asm (".pushsection .text.bootstrap
	"
     "jmp kmain
	"
     ".popsection");

extern uintptr_t __bss_start[];
extern uintptr_t __bss_end[];

/* Zero the BSS section */
static inline void zero_bss()
{
    uint32_t *memloc = __bss_start;

    while (memloc < __bss_end)
        *memloc++ = 0;
}

/* JASOS kernel C entrypoint */
void kmain()
{
    /* We need to zero out the BSS section */
    zero_bss();

    writetty_str("

Hello, world!

");
    return;
}

连接器的文字和boot子从本回答中提出的第一版没有修改。

在基欧马斯大学经营时,产出应类似于:

“entergraph


Footnotes:

  • <>1> https://www.codeproject.com/Articles/664165/Writing-a-officeer-in-Assembly-and-C-Part” rel=“noretinger”>“在C中打上一个载荷”是《法典》项目指南。 它被评为很高的等级,在某一点上逐月发表。 Unfortunitely 和许多涉及在线集会的教员一样,他们教授许多不良习惯,并做错东西。 他们很幸运,可以与他们确实使用的汇编商合作。 许多人试图利用这些坏想法与海合会合写真实的ker子,并且错失。 我将《法典》项目提一下,因为它过去是许多关于证券流通问题的基础。 如同许多其他理论一样,它实际上完全可以信赖。 其中一个例外是:。 C中带有gcc的真正模式:写上载荷

    我提供了第二部法典样本,作为微小的完全可核查的范例,以显示海合会在网上集会上想要印刷一种特性并印刷一部插图。 那里很少有条款表明如何适当利用海湾合作委员会。 第二个例子表明,在C职能范围内撰写的组装编码与撰写C功能之间有差别,如书目信息系统电话等所需物品的组装低。 如果您将使用GCC,以总结整个组装规范职能,那么,从编组的职能开始,就很难写上文字。 这违背了使用C的目的。

问题回答

暂无回答




相关问题
gcc -fPIC seems to muck with optimization flags

Following along from this question: how-do-i-check-if-gcc-is-performing-tail-recursion-optimization, I noticed that using gcc with -fPIC seems to destroy this optimization. I am creating a shared ...

Generate assembler code from C file in linux

I would like to know how to generate assembler code from a C program using Unix. I tried the gcc: gcc -c file.c I also used firstly cpp and then try as but I m getting errors. I m trying to build an ...

Getting rid of pre-compiled headers

OK, I have old Metrowerks code for Mac and Windows where the previous developer used pre-compiled headers for every project that this code base builds. How does one get rid of Pre-compiled headers, ...

Include a .txt file in a .h in C++?

I have a number of places where I need to re-use some template code. Many classes need these items In a .h could I do something like: #include <xxx.txt> and place all of this code in the ....

How to compile for Mac OS X 10.5

I d like to compile my application for version 10.5 and forward. Ever since I upgraded to Snow Leopard and installed the latest XCode, gcc defaults to 10.6. I ve tried -isysroot /Developer/SDKs/...

热门标签