Skip to content

Instantly share code, notes, and snippets.

@lain-dono
Last active August 29, 2015 13:57
Show Gist options
  • Save lain-dono/9635096 to your computer and use it in GitHub Desktop.
Save lain-dono/9635096 to your computer and use it in GitHub Desktop.

Собираем стартовый файл i686-elf-as -o boot.o boot.s

Собираем main.c i686-elf-gcc -nostdlib -nostartfiles -ffreestanding -std=c99 -c kernel_main.c -o kernel_main.o

Линкуем всё в kernel i686-elf-ld -T linker.ld -o kernel boot.o kernel_main.o

Запускаем qemu-system-i386 -m 128 -kernel kernel

# Объявляем константы для multiboot-заголовка
.set ALIGN, 1<<0
.set MEMINFO, 1<<1
.set FLAGS, ALIGN | MEMINFO
.set MAGIC, 0x1BADB002
.set CHECKSUM, -(MAGIC + FLAGS)
# Собсна сам заголовок
# Подробнее лучше всего можно почитать
# https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
# или перевод http://gownos.blogspot.ru/2011/10/multiboot-specification.html
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
# Резервируем место под стек
.section .bootstrap_stack, "aw", @nobits
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
# The kernel entry point.
.section .text
.global _start
.type _start, @function
_start:
movl $stack_top, %esp
# Обнуляем EFLAGS.
pushl $0
popf
# Push the pointer to the Multiboot information structure.
# Добавляем в стек указатель на multiboot-структуру
pushl %ebx
# Добавляем в стек магическое число для проверки валидности multiboot-структуры
pushl %eax
# Прыгаем к main
call kernel_main
# Выключаем обработку прерываний
cli
hlt
# Бесконечный цикл
.Lhang:
jmp .Lhang
.size _start, . - _start
ENTRY(_start)
SECTIONS
{
. = 1M;
.text BLOCK(4K) : ALIGN(4K) { *(.multiboot) *(.text) }
.rodata BLOCK(4K) : ALIGN(4K) { *(.rodata) }
.data BLOCK(4K) : ALIGN(4K) { *(.data) }
.bss BLOCK(4K) : ALIGN(4K) { *(COMMON) *(.bss) *(.bootstrap_stack) }
}
// Будем рисовать символы на текстовом VGA-экране
#define VGA_MEM(i) (*(volatile unsigned char*)(0xB8000+i))
void puts (const char * str) {
int i=0;
while (*str) {
VGA_MEM(i) = (*str++);
i+=2;
}
}
int kernel_main(void) {
int i=80*40;
while(i--) VGA_MEM(i*2) = 0; // Очищаем экран
puts ("hello, world!\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment