Задать вопрос
@halwarsing
Я python и Web программист.

Как увеличить памяти для переменных и функций ядра на C?

При достижении или больше определённого количества переменных или функций, перестают работать все string literals в ядре C, как можно увеличить память для них?

загрузчик mbr.asm:

[org 0x7c00]
KERNEL_OFFSET equ 0x1000 ; The same one we used when linking the kernel

mov [BOOT_DRIVE], dl ; Remember that the BIOS sets us the boot drive in 'dl' on boot
mov bp, 0x8000 ; 0x8000
mov sp, bp

mov bx, MSG_16BIT_MODE
call print16
call print16_nl

call load_kernel ; read the kernel from disk
call switch_to_32bit ; disable interrupts, load GDT,  etc. Finally jumps to 'BEGIN_PM'
jmp $ ; Never executed

%include "boot/print-16bit.asm"
%include "boot/print-32bit.asm"
%include "boot/disk.asm"
%include "boot/gdt.asm"
%include "boot/switch-to-32bit.asm"

[bits 16]
load_kernel:
    mov bx, MSG_LOAD_KERNEL
    call print16
    call print16_nl

    mov bx, KERNEL_OFFSET ; Read from disk and store in 0x1000
    mov dh, 54 ;31 or 54
    mov dl, [BOOT_DRIVE]
    call disk_load
    ret

[bits 32]
BEGIN_32BIT:
    mov ebx, MSG_32BIT_MODE
    call print32
    call KERNEL_OFFSET ; Give control to the kernel
    jmp $ ; Stay here when the kernel returns control to us (if ever)


BOOT_DRIVE db 0 ; It is a good idea to store it in memory because 'dl' may get overwritten
MSG_16BIT_MODE db "Started in 16-bit Real Mode", 0
MSG_32BIT_MODE db "Landed in 32-bit Protected Mode", 0
MSG_LOAD_KERNEL db "Loading kernel into memory", 0

; padding
times 510 - ($-$$) db 0
dw 0xaa55


Загрузка с диска disk.asm:

; load 'dh' sectors from drive 'dl' into ES:BX
disk_load:
    pusha
    ; reading from disk requires setting specific values in all registers
    ; so we will overwrite our input parameters from 'dx'. Let's save it
    ; to the stack for later use.
    push dx

    mov ah, 0x02 ; ah <- int 0x13 function. 0x02 = 'read'
    mov al, dh   ; al <- number of sectors to read (0x01 .. 0x80)
    mov cl, 0x02 ; cl <- sector (0x01 .. 0x11)
                 ; 0x01 is our boot sector, 0x02 is the first 'available' sector
    mov ch, 0x00 ; ch <- cylinder (0x0 .. 0x3FF, upper 2 bits in 'cl')
    ; dl <- drive number. Our caller sets it as a parameter and gets it from BIOS
    ; (0 = floppy, 1 = floppy2, 0x80 = hdd, 0x81 = hdd2)
    mov dh, 0x00 ; dh <- head number (0x0 .. 0xF)

    ; [es:bx] <- pointer to buffer where the data will be stored
    ; caller sets it up for us, and it is actually the standard location for int 13h
    int 0x13      ; BIOS interrupt
    jc disk_error ; if error (stored in the carry bit)

    pop dx
    cmp al, dh    ; BIOS also sets 'al' to the # of sectors read. Compare it.
    jne sectors_error
    popa
    ret


disk_error:
    mov bx, DISK_ERROR
    call print16
    call print16_nl
    mov dh, ah ; ah = error code, dl = disk drive that dropped the error
    call print16_hex ; check out the code at http://stanislavs.org/helppc/int_13-1.html
    jmp disk_loop

sectors_error:
    mov bx, SECTORS_ERROR
    call print16

disk_loop:
    jmp $

DISK_ERROR: db "Disk read error", 0
SECTORS_ERROR: db "Incorrect number of sectors read", 0


gdt.asm:

gdt_start: ; don't remove the labels, they're needed to compute sizes and jumps
    ; the GDT starts with a null 8-byte
    dd 0x0 ; 4 byte
    dd 0x0 ; 4 byte

; GDT for code segment. base = 0x00000000, length = 0xfffff
; for flags, refer to os-dev.pdf document, page 36
gdt_code:
    dw 0xffff    ; segment length, bits 0-15
    dw 0x0       ; segment base, bits 0-15
    db 0x0       ; segment base, bits 16-23
    db 10011010b ; flags (8 bits)
    db 11001111b ; flags (4 bits) + segment length, bits 16-19
    db 0x0       ; segment base, bits 24-31

; GDT for data segment. base and length identical to code segment
; some flags changed, again, refer to os-dev.pdf
gdt_data:
    dw 0xffff
    dw 0x0
    db 0x0
    db 10010010b
    db 11001111b
    db 0x0

gdt_end:

; GDT descriptor
gdt_descriptor:
    dw gdt_end - gdt_start - 1 ; size (16 bit), always one less of its true size
    dd gdt_start ; address (32 bit)

; define some constants for later use
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start


загрузчик кода в C - kernel-entry.asm:

global _start
[bits 32]

_start:
    [extern _start_kernel] ; Define calling point. Must have same name as kernel.c 'main' function
    call _start_kernel ; Calls the C function. The linker will know where it is placed in memory
    jmp $


GNU Linker linker.ld:

ENTRY(_start)

SECTIONS
{
	. = 0x1000;
	.text : { *(.text) }
	.data : { *(.data) }
	.bss  : { *(.bss) *(COMMON) }
}


компиляция на Windows compile.bat:

gcc -ffreestanding -m32 -g -c kernel/kernel.c -o kernel/kernel.o -std=c11
gcc -ffreestanding -m32 -g -c kernel/util.c -o kernel/util.o -std=c11
gcc -ffreestanding -m32 -g -c kernel/mem.c -o kernel/mem.o -std=c11
gcc -ffreestanding -m32 -g -c kernel/system.c -o kernel/system.o -std=c11

gcc -ffreestanding -m32 -g -c drivers/ports.c -o drivers/ports.o -std=c11
gcc -ffreestanding -m32 -g -c drivers/display.c -o drivers/display.o -std=c11
gcc -ffreestanding -m32 -g -c drivers/keyboard.c -o drivers/keyboard.o -std=c11

gcc -ffreestanding -m32 -g -c cpu/idt.c -o cpu/idt.o -std=c11
gcc -ffreestanding -m32 -g -c cpu/isr.c -o cpu/isr.o -std=c11
gcc -ffreestanding -m32 -g -c cpu/timer.c -o cpu/timer.o -std=c11

nasm -fbin boot/mbr.asm -o boot/mbr.bin
nasm -felf boot/kernel-entry.asm -o boot/kernel-entry.o
nasm -felf cpu/interrupt.asm -o cpu/interrupt.o

ld -mi386pe -no-PIE -o kernel.out -Tlinker.ld boot/kernel-entry.o kernel/kernel.o  kernel/util.o kernel/mem.o drivers/ports.o drivers/display.o drivers/keyboard.o cpu/idt.o cpu/interrupt.o cpu/isr.o cpu/timer.o kernel/system.o
objcopy -I elf32-i386 kernel.out kernel.elf
objcopy -O binary kernel.elf kernel.bin
type boot\\mbr.bin kernel.bin > os-image.bin
qemu-system-i386 -fda os-image.bin


readelf -a kernel.elf в двух случаях: https://pastebin.com/kTgGc2Yd
  • Вопрос задан
  • 205 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
При достижении или больше определённого количества переменных или функций, перестают работать все string literals в ядре C

Определённого -- это какого?

Вот тут
mov bx, KERNEL_OFFSET ; Read from disk and store in 0x1000
    mov dh, 54 ;31 or 54

ты 54 сектора ядра загружаешь в память. Есть какая-нибудь корреляция?

как можно увеличить память для них?

код ядра ты не привёл, что там ломается можно только догадываться, ну ты понял.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы