Dies ist eine alte Version des Dokuments!
Füge sowas hinzu:
#define VGA_CRTC_INDEX 0x3D4
#define VGA_CRTC_DATA 0x3D5
static inline void vga_set_cursor(uint16 pos) {
outb(VGA_CRTC_INDEX, 0x0F);
outb(VGA_CRTC_DATA, (uint8)(pos & 0xFF));
outb(VGA_CRTC_INDEX, 0x0E);
outb(VGA_CRTC_DATA, (uint8)((pos >> 8) & 0xFF));
}
Und ruf es jedes Mal auf, wenn du vga_index änderst, z.B. am Ende von:
void print_char(char ch)
{
vga_buffer[vga_index] = vga_entry(ch, g_fore_color, g_back_color);
vga_index++;
vga_set_cursor((uint16)vga_index);
}
void print_new_line()
{
if(next_line_index > (BUFSIZE / 80) - 3){
next_line_index = 0;
clear_vga_buffer(&vga_buffer, WHITE, BLUE);
}
vga_index = 80 * next_line_index;
next_line_index++;
vga_set_cursor((uint16)vga_index);
}
Und auch beim Backspace-Zweig nach vga_index--.
else if(keycode == KEY_BACKSPACE) {
if (strc > 0 && vga_index > 80*(next_line_index-1) + 2) {
vga_index--;
strc--;
str[strc] = 0; // <- WICHTIG: String kürzen / terminieren
vga_buffer[vga_index] = vga_entry(' ', WHITE, BLUE);
vga_set_cursor((uint16)vga_index);
}
}
Hallo Besucher! Willkommen in diesem kleinen Wiki rund um IT. Vieles ist noch unvollständig, unstrukturiert oder vielleicht sogar falsch bzw. irreführend.
Du kannst Artikel gerne ergänzen oder verbessern. Gerne mit so vielen Links wie nötig. Bitte keine Werbelinks und nur selbst verfasste oder lizenzfreie Texte! Copyright beachten!
Eine Liste von Seiten die noch erstellt werden müssen.
config system interface
edit port1
set ip 172.21.1.167 255.255.254.0
set allowaccess ping
next
edit port2
set ip 10.100.0.1 255.255.255.0
set allowaccess ping
next
end
config router static
edit 1
set gateway 172.21.0.1
set device port1
next
end
config firewall policy
edit 1
set name "LAN-to-WAN"
set srcintf "port2"
set dstintf "port1"
set srcaddr "all"
set dstaddr "all"
set schedule "always"
set service "ALL"
set action accept
set nat enable
next
end
┌──(manuel㉿kali)-[~/kernel] └─$ cat run.sh #assemble boot.s file as --32 boot.s -o boot.o #compile kernel.c file gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra gcc -m32 -c utils.c -o utils.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra gcc -m32 -c char.c -o char.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra #linking the kernel with kernel.o and boot.o files ld -m elf_i386 -T linker.ld kernel.o utils.o char.o boot.o -o MyOS.bin -nostdlib #check MyOS.bin file is x86 multiboot file or not grub-file --is-x86-multiboot MyOS.bin #building the iso file mkdir -p isodir/boot/grub cp MyOS.bin isodir/boot/MyOS.bin cp grub.cfg isodir/boot/grub/grub.cfg grub-mkrescue -o MyOS.iso isodir #run it in qemu qemu-system-x86_64 -cdrom MyOS.iso ┌──(manuel㉿kali)-[~/kernel] └─$ bash run.sh ld: kernel.o: in function loop': kernel.c:(.text+0x230): undefined reference to strcmp' grub-file: error: cannot open `MyOS.bin': No such file or directory. cp: cannot stat 'MyOS.bin': No such file or directory xorriso 1.5.6 : RockRidge filesystem manipulator, libburnia project. Drive current: -outdev 'stdio:MyOS.iso' Media current: stdio file, overwriteable Media status : is blank Media summary: 0 sessions, 0 data blocks, 0 data, 10.6g free Added to ISO image: directory '/'='/tmp/grub.imWglf' xorriso : UPDATE : 338 files added in 1 seconds Added to ISO image: directory '/'='/home/manuel/kernel/isodir' xorriso : UPDATE : 341 files added in 1 seconds xorriso : NOTE : Copying to System Area: 512 bytes from file '/usr/lib/grub/i386-pc/boot_hybrid.img' ISO image produced: 5057 sectors Written to medium : 5057 sectors at LBA 0 Writing to 'stdio:MyOS.iso' completed successfully. QEMU sagt error: file '/boot/myOS.bin' not found
Warum der Build fehlschlägt (undefined reference to strcmp)
Die entscheidende Zeile ist:
text
ld: kernel.o: in function `loop':
kernel.c:(.text+0x230): undefined reference to `strcmp'
Du baust ein freestanding Kernel-Binary:
Bash
gcc -m32 ... -ffreestanding -nostdlib
In so einem Umfeld gibt es keine libc, also auch kein fertiges strcmp.
Du rufst strcmp in kernel.c aber auf, ohne es selbst zu implementieren.
Lösung: Implementiere strcmp selbst, z.B. in utils.c:
C
// utils.c
int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return (unsigned char)*s1 - (unsigned char)*s2;
}
Und in der Header-Datei, die du in kernel.c einbindest (z.B. utils.h):
C
int strcmp(const char *s1, const char *s2);
Danach neu bauen:
Bash
bash run.sh
Wenn ld dann ohne Fehler durchläuft, wird MyOS.bin angelegt und der Rest der Befehle funktioniert wieder.
Warum GRUB in QEMU '/boot/myOS.bin' not found meldet
QEMU/GRUB-Fehler:
text
error: file '/boot/myOS.bin' not found
In deinem Script kopierst du:
Bash
cp MyOS.bin isodir/boot/MyOS.bin
Also mit großem M: MyOS.bin.
In der Fehlermeldung sucht GRUB aber nach myOS.bin (kleines m).
ISO9660/GRUB sind hier case‑sensitiv, d.h. MyOS.bin und myOS.bin sind unterschiedliche Dateien.
Lösung: In deiner grub.cfg (liegt bei dir in grub.cfg, wird nach isodir/boot/grub/grub.cfg kopiert), muss dasselbe exakt so stehen, wie du die Datei kopierst, z.B.:
cfg
menuentry "MyOS" {
multiboot /boot/MyOS.bin
boot
}
Achte auf:
Pfad: /boot/MyOS.bin
Groß-/Kleinschreibung: exakt wie im cp‑Befehl.
Warum grub-file und cp meckern
Nach dem ld‑Fehler wird MyOS.bin gar nicht erzeugt, deshalb:
text
grub-file: error: cannot open `MyOS.bin': No such file or directory.
cp: cannot stat 'MyOS.bin': No such file or directory
Das ist nur eine Folge des ersten Fehlers (strcmp). Sobald du strcmp implementierst und ld erfolgreich ist, verschwinden diese Meldungen.
Kleiner Qualitäts-Tipp für dein Script
Ganz oben in run.sh:
Bash
#!/bin/bash
set -e
Dann bricht das Script sofort ab, wenn ein Befehl fehlschlägt (z.B. ld), und du baust nicht versehentlich ein ISO ohne Kernel.
Optional zusätzlich:
Bash
rm -rf isodir
vor mkdir -p isodir/boot/grub, damit nicht alte Dateien in den neuen Build rutschen.
Zusammenfassung der Schritte:
strcmp selbst implementieren (z.B. in utils.c) und deklarieren.
In grub.cfg denselben Dateinamen wie in cp benutzen (/boot/MyOS.bin vs /boot/myOS.bin).
Script mit set -e absichern.
bash run.sh erneut ausführen, dann QEMU starten.
Wenn du magst, poste kernel.c, utils.c und grub.cfg, dann kann ich dir konkret zeigen, wo du was einfügen musst.
// utils.c
int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return (unsigned char)*s1 - (unsigned char)*s2;
}
# utils.h extern int strcmp(const char *s1, const char *s2);