bss section mit null initialiseren



  • Wie sieht ein eleganter Startcode in Assembler aus, der die bss section (evtl. auch COMMON) zuverlässig "nullt"?

    Bisher (kernel.asm von PrettyOS):

    [Bits 32]
    section .text          ; ld needs that for coff format
    
    [global KernelStart]
    KernelStart:
        mov    ax, 0x10
        mov    ds, ax      ; data descriptor --> data, stack and extra segment
        mov    ss, ax           
        mov    es, ax
        xor    eax, eax    ; null desriptor --> FS and GS
        mov    fs, ax
        mov    gs, ax
        mov    esp, 0x200000 ; set stack below 2 MB limit
    
    [extern _main]         ; entry point in ckernel.c
    	call _main ; ->-> C-Kernel
        jmp $
    
    ; hier fehlt nun diese Anweisung, oder macht man das mit einer Schleife?
    

    Linkerskript:

    OUTPUT_FORMAT("binary")
    ENTRY(KernelStart)
    SECTIONS
    { 
      . = 0x00010000;
      .text   : { *(EXCLUDE_FILE(shared_pages.o).text) } 
      . = 0x00017000;
      .text1  : { shared_pages.o(.text)                } 
      . = 0x00018000;
      .data   : { *(.data)                             } 	
      .rodata : { *(.rodata)                           }
      .bss    : { *(.bss) *(COMMON)                    } 
    }
    

    Wie erledigt crt0 dies genau?



  • Ja, das macht man in einer Schleife. Dazu legst du die an den Anfang der BSS-Sektion und ans Ende jeweils ein Symbol.

    ...
    .bss    : { __bss_start = .; *(.bss) *(COMMON)                    } 
    __end = .;
    

    Dann überschreibst du den Speicher von __bss_start bis __end (nicht inklusive) mit Nullen.



  • Linker-Skript:

    OUTPUT_FORMAT("binary")
    ENTRY(KernelStart)
    SECTIONS
    { 
      . = 0x00010000;
      .text   : { __code_start = .;   *(EXCLUDE_FILE(shared_pages.o).text) } 
      . = 0x00017000;
      .text1  : { shared_pages.o(.text)                            } 
      . = 0x00018000;
      .data   : { __data_start = .;   *(.data)                             } 	
      .rodata : { __rodata_start = .; *(.rodata)                           }
      .bss    : { __bss_start = .;    *(.bss) *(COMMON)                    } 
      __end = .;
    }
    


  • Was soll ich dazu sagen außer: brilliant!



  • Was soll ich dazu sagen außer: brilliant!

    Je kryptischer, desto besser? 😃

    Könntest mir noch bei der Zählschleife in kernel.asm helfen, bin leider nicht geübt in Assembler. Idee:
    ; Anfang auf __bss_start setzen
    mov ecx, [__end - __bss_start]
    .Schleife:
    ; Anweisung: setze speicherstelle auf (byte) null
    loop .Schleife

    oder geht das einfacher mit einer Superanweisung in einer Zeile?
    Irgendwas mit times oder space oder ...?

    Wie sieht das in crt0.s aus? 🙂



  • extern __bss_start
    extern __end
    
    	mov edi, __bss_start
    	mov ecx, __end
    	sub ecx, __bss_start
    	mov al, 0
    	rep stosb
    


  • danke! 👍

    kernel.asm:

    [Bits 32]
    section .text          ; ld needs that for coff format
    
    [global KernelStart]
    KernelStart:
        mov    ax, 0x10
        mov    ds, ax      ; data descriptor --> data, stack and extra segment
        mov    ss, ax           
        mov    es, ax
        xor    eax, eax    ; null desriptor --> FS and GS
        mov    fs, ax
        mov    gs, ax
        mov    esp, 0x200000 ; set stack below 2 MB limit
    
    	extern __bss_start
        extern __end
        mov edi, __bss_start
        mov ecx, __end
        sub ecx, __bss_start
        mov al, 0
        rep stosb
    
    [extern _main]         ; entry point in ckernel.c
    	call _main ; ->-> C-Kernel
        jmp $
    


  • Es sollte auch gehen das in C mittels memset zu machen.



  • Lüttmoor schrieb:

    Es sollte auch gehen das in C mittels memset zu machen.

    Das gefällt mir aber besser in Assembler, habe eine solche Datei ja auch in der User-Sektion, da muss wahrscheinlich auch noch so etwas rein, sieht bisher so aus:

    ENTRY(_start)
    OUTPUT_FORMAT(elf32-i386)
    SECTIONS
    {
        . = 0x400000;
    	.text : { *(.text*)             }
        .data : { *(.data*) *(.rodata*) }
        .bss :  { *(.bss)   *(COMMON)   }
    }
    
    ; start.asm
    
    [BITS 32]
    extern _main
    global _start
    
    _start:
        mov esp, 0x600000 
        call _main
    end:
        jmp end
    

    jetzt so:

    ENTRY(_start)
    OUTPUT_FORMAT(elf32-i386)
    SECTIONS
    {
        . = 0x400000;
    	.text   : { __code_start = .;   *(.text*)         }
    	.data   : { __data_start = .;   *(.data)          }    
        .rodata : { __rodata_start = .; *(.rodata)        }
        .bss    : { __bss_start = .;    *(.bss) *(COMMON) }
         __end = .; 	
    }
    
    ; start.asm
    
    [BITS 32]
    extern __bss_start
    extern __end
    extern _main
    global _start
    
    _start:
        mov edi, __bss_start
        mov ecx, __end
        sub ecx, __bss_start
        mov al, 0
        rep stosb  ; repeats instruction decrementing ECX until zero
    	           ; and stores value from AL incrementing ES:EDI
    
    	mov esp, 0x600000 ; stackpointer
        call _main
    
        jmp $
    

    🙂


Anmelden zum Antworten