programa - ¿Cómo puedo crear una imagen de CD de arranque con mi kernel?
programa para bootear usb linux (1)
Primero te doy una idea básica de cómo funciona realmente el proceso de arranque. De hecho, cuando ejecutas el comando qemu-system-i386 -kernel kernel.bin
Qemu carga tu binario del kernel en la memoria en la ubicación 0x7c000 desde donde continúa el arranque. Si desea arrancar desde ISO, debe indicarle al BIOS que hay una imagen de arranque (marque el indicador de arranque) en mi iso, y darle las instrucciones adecuadas para cargar su kernel.
¿Como hacer eso?
Tienes que configurar un Bootloader que tu BIOS pueda cargar en 0x7c000 y más tarde. Cargará tu Kernel Image en la memoria y saltará al punto de entrada del kernel.
Por lo tanto, marque su ISO activo (indicador de arranque) y agregue código de cargador de arranque.
Puedo ver que ya has configurado el código de punto de entrada multiarranque
align 4
dd 0x1BADB002
dd 0x00
dd - (0x1BADB002 + 0x00)
Puede leer más sobre cómo configurar la cadena de arranque de grub desde aquí http://wiki.osdev.org/GRUB_2 También puede usar el gestor de arranque syslinux http://www.syslinux.org/wiki/index.php?title=The_Syslinux_Project
syslinux Copie isolinux.bin, syslinux.cfg y mboot.c32 en su ruta de compilación de la imagen binaria de su kernel. configure syslinux.cfg y ejecute el siguiente comando.
mkisofs.exe -o %OUTPUT_DIR%/%BUILD_NAME%.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table %ISO_DIR%
Tengo un kernel, para arrancar estoy usando el comando qemu-system-i386 -kernel kernel.bin
. ¿Hay alguna forma de crear una imagen de disco de arranque para iniciar con qemu-system-i386 -cdrom CD.iso
?
El código que estoy compilando en Linux con estos comandos:
nasm -f elf32 kernel.asm -o kernelasm.o
gcc -m32 -c kernel.c -o kernelc.o
ld -m elf_i386 -T link.ld -o kernel.bin kernelasm.o kernelc.o
y luego arrancando con qemu-system-i386 -kernel kernel.bin
CÓDIGO: kernel.asm:
[BITS 32]
SECTION .text
align 4
dd 0x1BADB002
dd 0x00
dd - (0x1BADB002 + 0x00)
global start
global keyboard_handler
global read_port
global write_port
global load_idt
extern kmain
extern keyboard_handler_main
read_port:
mov edx, [esp + 4]
in al, dx
ret
write_port:
mov edx, [esp + 4]
mov al, [esp + 4 + 4]
out dx, al
ret
load_idt:
mov edx, [esp + 4]
lidt [edx]
sti
ret
keyboard_handler:
call keyboard_handler_main
iretd
start:
cli
mov esp, stack_space
call kmain
hlt
section .bss
resb 8192
stack_space:
kernel.c:
#include "keyboard_map.h"
#define LINES 25
#define COLUMNS_IN_LINE 80
#define BYTES_FOR_EACH_ELEMENT 2
#define SCREENSIZE BYTES_FOR_EACH_ELEMENT * COLUMNS_IN_LINE * LINES
#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_STATUS_PORT 0x64
#define IDT_SIZE 256
#define INTERRUPT_GATE 0x8e
#define KERNEL_CODE_SEGMENT_OFFSET 0x08
#define ENTER_KEY_CODE 0x1C
extern unsigned char keyboard_map[128];
extern void keyboard_handler(void);
extern char read_port(unsigned short port);
extern void write_port(unsigned short port, unsigned char data);
extern void load_idt(unsigned long *idt_ptr);
unsigned int current_loc = 0;
char *vidptr = (char*)0xb8000;
struct IDT_entry {
unsigned short int offset_lowerbits;
unsigned short int selector;
unsigned char zero;
unsigned char type_attr;
unsigned short int offset_higherbits;
};
struct IDT_entry IDT[IDT_SIZE];
void idt_init(void)
{
unsigned long keyboard_address;
unsigned long idt_address;
unsigned long idt_ptr[2];
keyboard_address = (unsigned long)keyboard_handler;
IDT[0x21].offset_lowerbits = keyboard_address & 0xffff;
IDT[0x21].selector = KERNEL_CODE_SEGMENT_OFFSET;
IDT[0x21].zero = 0;
IDT[0x21].type_attr = INTERRUPT_GATE;
IDT[0x21].offset_higherbits = (keyboard_address & 0xffff0000) >> 16;
write_port(0x20 , 0x11);
write_port(0xA0 , 0x11);
write_port(0x21 , 0x20);
write_port(0xA1 , 0x28);
write_port(0x21 , 0x00);
write_port(0xA1 , 0x00);
write_port(0x21 , 0x01);
write_port(0xA1 , 0x01);
write_port(0x21 , 0xff);
write_port(0xA1 , 0xff);
idt_address = (unsigned long)IDT ;
idt_ptr[0] = (sizeof (struct IDT_entry) * IDT_SIZE) + ((idt_address & 0xffff) << 16);
idt_ptr[1] = idt_address >> 16 ;
load_idt(idt_ptr);
}
void kb_init(void)
{
write_port(0x21 , 0xFD);
}
void kprint(const char *str)
{
unsigned int i = 0;
while (str[i] != ''/0'') {
vidptr[current_loc++] = str[i++];
vidptr[current_loc++] = 0x07;
}
}
void kprint_newline(void)
{
unsigned int line_size = BYTES_FOR_EACH_ELEMENT * COLUMNS_IN_LINE;
current_loc = current_loc + (line_size - current_loc % (line_size));
}
void clear_screen(void)
{
unsigned int i = 0;
while (i < SCREENSIZE) {
vidptr[i++] = '' '';
vidptr[i++] = 0x07;
}
}
void keyboard_handler_main(void)
{
unsigned char status;
char keycode;
write_port(0x20, 0x20);
status = read_port(KEYBOARD_STATUS_PORT);
if (status & 0x01) {
keycode = read_port(KEYBOARD_DATA_PORT);
if(keycode < 0)
return;
if(keycode == ENTER_KEY_CODE) {
kprint_newline();
return;
}
vidptr[current_loc++] = keyboard_map[(unsigned char) keycode];
vidptr[current_loc++] = 0x07;
}
}
void kmain(void)
{
const char *str = "my first kernel with keyboard support";
clear_screen();
kprint(str);
kprint_newline();
kprint_newline();
idt_init();
kb_init();
while(1);
}
keyboard_map.h:
unsigned char keyboard_map[128] =
{
0, 27, ''1'', ''2'', ''3'', ''4'', ''5'', ''6'', ''7'', ''8'', /* 9 */
''9'', ''0'', ''-'', ''='', ''/b'', /* Backspace */
''/t'', /* Tab */
''q'', ''w'', ''e'', ''r'', /* 19 */
''t'', ''y'', ''u'', ''i'', ''o'', ''p'', ''['', '']'', ''/n'', /* Enter key */
0, /* 29 - Control */
''a'', ''s'', ''d'', ''f'', ''g'', ''h'', ''j'', ''k'', ''l'', '';'', /* 39 */
''/''', ''`'', 0, /* Left shift */
''//', ''z'', ''x'', ''c'', ''v'', ''b'', ''n'', /* 49 */
''m'', '','', ''.'', ''/'', 0, /* Right shift */
''*'',
0, /* Alt */
'' '', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
''-'',
0, /* Left Arrow */
0,
0, /* Right Arrow */
''+'',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};
link.ld:
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
{
. = 0x100000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}