{"id":15859828,"url":"https://github.com/simar7/qemu-kconfig-demo","last_synced_at":"2025-06-20T23:36:35.865Z","repository":{"id":145549754,"uuid":"9804543","full_name":"simar7/qemu-kconfig-demo","owner":"simar7","description":null,"archived":false,"fork":false,"pushed_at":"2013-05-03T17:40:10.000Z","size":984,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-01T20:37:29.330Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simar7.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-05-02T02:51:05.000Z","updated_at":"2013-11-20T02:59:58.000Z","dependencies_parsed_at":"2023-03-30T02:47:53.241Z","dependency_job_id":null,"html_url":"https://github.com/simar7/qemu-kconfig-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/simar7/qemu-kconfig-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simar7%2Fqemu-kconfig-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simar7%2Fqemu-kconfig-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simar7%2Fqemu-kconfig-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simar7%2Fqemu-kconfig-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simar7","download_url":"https://codeload.github.com/simar7/qemu-kconfig-demo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simar7%2Fqemu-kconfig-demo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261037152,"owners_count":23100933,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-05T21:23:57.401Z","updated_at":"2025-06-20T23:36:30.856Z","avatar_url":"https://github.com/simar7.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"This code implements an X86 legacy bios.  It is intended to be\ncompiled using standard gnu tools (eg, gas and gcc).\n\nTo build, one should be able to run \"make\" in the main directory.  The\nresulting file \"out/bios.bin\" contains the processed bios image.\n\n\nTesting of images:\n\nTo test the bios under bochs, one will need to instruct bochs to use\nthe new bios image.  Use the 'romimage' option - for example:\n\nbochs -q 'floppya: 1_44=myfdimage.img' 'romimage: file=out/bios.bin'\n\nTo test under qemu, one will need to create a directory with all the\nbios images and then overwrite the main bios image.  For example:\n\ncp /usr/share/qemu/*.bin mybiosdir/\ncp out/bios.bin mybiosdir/\ncp out/*.aml mybiosdir/\n\nOnce this is setup, one can instruct qemu to use the newly created\ndirectory for rom images.  For example:\n\nqemu -L mybiosdir/ -fda myfdimage.img\n\n\nOverview of files:\n\nThe src/ directory contains the bios source code.  Several of the\nfiles are compiled twice - once for 16bit mode and once for 32bit\nmode.  (The build system will remove code that is not needed for a\nparticular mode.)\n\nThe tools/ directory contains helper utilities for manipulating and\nbuilding the final rom.\n\nThe out/ directory is created by the build process - it contains all\ntemporary and final files.\n\n\nBuild overview:\n\nThe 16bit code is compiled via gcc to assembler (file out/ccode.16.s).\nThe gcc \"-fwhole-program\" and \"-ffunction-sections -fdata-sections\"\noptions are used to optimize the process so that gcc can efficiently\ncompile and discard unneeded code.  (In the code, one can use the\nmacros 'VISIBLE16' and 'VISIBLE32FLAT' to instruct a symbol to be\noutputted in 16bit and 32bit mode respectively.)\n\nThis resulting assembler code is pulled into romlayout.S.  The gas\noption \".code16gcc\" is used prior to including the gcc generated\nassembler - this option enables gcc to generate valid 16 bit code.\n\nThe post code (post.c) is entered, via the function handle_post(), in\n32bit mode.  The 16bit post vector (in romlayout.S) transitions the\ncpu into 32 bit mode before calling the post.c code.\n\nIn the last step of compilation, the 32 bit code is merged into the 16\nbit code so that one binary file contains both.  Currently, both 16bit\nand 32bit code will be located in the memory at 0xe0000-0xfffff.\n\n\nGCC 16 bit limitations:\n\nAlthough the 16bit code is compiled with gcc, developers need to be\naware of the environment.  In particular, global variables _must_ be\ntreated specially.\n\nThe code has full access to stack variables and general purpose\nregisters.  The entry code in romlayout.S will push the original\nregisters on the stack before calling the C code and then pop them off\n(including any required changes) before returning from the interrupt.\nChanges to CS, DS, and ES segment registers in C code is also safe.\nChanges to other segment registers (SS, FS, GS) need to be restored\nmanually.\n\nStack variables (and pointers to stack variables) work as they\nnormally do in standard C code.\n\nHowever, variables stored outside the stack need to be accessed via\nthe GET_VAR and SET_VAR macros (or one of the helper macros described\nbelow).  This is due to the 16bit segment nature of the X86 cpu when\nit is in \"real mode\".  The C entry code will set DS and SS to point to\nthe stack segment.  Variables not on the stack need to be accessed via\nan explicit segment register.  Any other access requires altering one\nof the other segment registers (usually ES) and then accessing the\nvariable via that segment register.\n\nThere are three low-level ways to access a remote variable:\nGET/SET_VAR, GET/SET_FARVAR, and GET/SET_FLATPTR.  The first set takes\nan explicit segment descriptor (eg, \"CS\") and offset.  The second set\nwill take a segment id and offset, set ES to the segment id, and then\nmake the access via the ES segment.  The last method is similar to the\nsecond, except it takes a pointer that would be valid in 32-bit flat\nmode instead of a segment/offset pair.\n\nMost BIOS variables are stored in global variables, the \"BDA\", or\n\"EBDA\" memory areas.  Because this is common, three sets of helper\nmacros (GET/SET_GLOBAL, GET/SET_BDA, and GET/SET_EBDA) are available\nto simplify these accesses.\n\nGlobal variables defined in the C code can be read in 16bit mode if\nthe variable declaration is marked with VAR16, VAR16VISIBLE,\nVAR16EXPORT, or VAR16FIXED.  The GET_GLOBAL macro will then allow read\naccess to the variable.  Global variables are stored in the 0xf000\nsegment.  Because the f-segment is marked read-only during run-time,\nthe 16bit code is not permitted to change the value of 16bit variables\n(use of the SET_GLOBAL macro from 16bit mode will cause a link error).\nCode running in 32bit mode can not access variables with VAR16, but\ncan access variables marked with VAR16VISIBLE, VAR16EXPORT,\nVAR16FIXED, or with no marking at all.  The 32bit code can use the\nGET/SET_GLOBAL macros, but they are not required.\n\n\nGCC 16 bit stack limitations:\n\nAnother limitation of gcc is its use of 32-bit temporaries.  Gcc will\nallocate 32-bits of space for every variable - even if that variable\nis only defined as a 'u8' or 'u16'.  If one is not careful, using too\nmuch stack space can break old DOS applications.\n\nThere does not appear to be explicit documentation on the minimum\nstack space available for bios calls.  However, Freedos has been\nobserved to call into the bios with less than 150 bytes available.\n\nNote that the post code and boot code (irq 18/19) do not have a stack\nlimitation because the entry points for these functions transition the\ncpu to 32bit mode and reset the stack to a known state.  Only the\ngeneral purpose 16-bit service entry points are affected.\n\nThere are some ways to reduce stack usage: making sure functions are\ntail-recursive often helps, reducing the number of parameters passed\nto functions often helps, sometimes reordering variable declarations\nhelps, inlining of functions can sometimes help, and passing of packed\nstructures can also help.  It is also possible to transition to/from\nan extra stack stored in the EBDA using the stack_hop helper function.\n\nSome useful stats: the overhead for the entry to a bios handler that\ntakes a 'struct bregs' is 42 bytes of stack space (6 bytes from\ninterrupt insn, 32 bytes to store registers, and 4 bytes for call\ninsn).  An entry to an ISR handler without args takes 30 bytes (6 + 20\n+ 4).\n\n\nDebugging the bios:\n\nThe bios will output information messages to a special debug port.\nUnder qemu, one can view these messages by adding '-chardev\nstdio,id=seabios -device isa-debugcon,iobase=0x402,chardev=seabios' to\nthe qemu command line.  Once this is done, one should see status\nmessages on the console.\n\nThe gdb-server mechanism of qemu is also useful.  One can use gdb with\nqemu to debug system images.  To use this, add '-s -S' to the qemu\ncommand line.  For example:\n\nqemu -L mybiosdir/ -fda myfdimage.img -s -S\n\nThen, in another session, run gdb with either out/rom16.o (to debug\nbios 16bit code) or out/rom32.o (to debug bios 32bit code).  For\nexample:\n\ngdb out/rom16.o\n\nOnce in gdb, use the command \"target remote localhost:1234\" to have\ngdb connect to qemu.  See the qemu documentation for more information\non using gdb and qemu in this mode.  Note that gdb seems to get\nbreakpoints confused when the cpu is in 16-bit real mode.  This makes\nstepping through the program difficult (though 'step instruction'\nstill works).  Also, one may need to set 16bit break points at both\nthe cpu address and memory address (eg, break *0x1234 ; break\n*0xf1234).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimar7%2Fqemu-kconfig-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimar7%2Fqemu-kconfig-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimar7%2Fqemu-kconfig-demo/lists"}