summaryrefslogtreecommitdiff
path: root/doc/dc0d32.blogspot.com_2010_06_real-mode-in-c-with-gcc-writing.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/dc0d32.blogspot.com_2010_06_real-mode-in-c-with-gcc-writing.txt')
-rw-r--r--doc/dc0d32.blogspot.com_2010_06_real-mode-in-c-with-gcc-writing.txt892
1 files changed, 892 insertions, 0 deletions
diff --git a/doc/dc0d32.blogspot.com_2010_06_real-mode-in-c-with-gcc-writing.txt b/doc/dc0d32.blogspot.com_2010_06_real-mode-in-c-with-gcc-writing.txt
new file mode 100644
index 0000000..6834acd
--- /dev/null
+++ b/doc/dc0d32.blogspot.com_2010_06_real-mode-in-c-with-gcc-writing.txt
@@ -0,0 +1,892 @@
+ #[1]dc0d32 - Atom [2]dc0d32 - RSS [3]dc0d32 - Atom
+
+[4]dc0d32
+
+Tuesday, June 15, 2010
+
+Real mode in C with gcc : writing a bootloader
+
+ Usually the x86 boot loader is written in assembler. We will be
+ exploring the possibility of writing one in C language (as much as
+ possible) compiled with gcc, and runs in real mode. Note that you can
+ also use the 16 bit bcc or TurboC compiler, but we will be focusing on
+ gcc in this post. Most open source kernels are compiled with gcc, and
+ it makes sense to write C bootloader with gcc instead of bcc as you get
+ a much cleaner toolchain :)
+ As of today (20100614), gcc 4.4.4 officially only emits code for
+ protected/long mode and does not support the real mode natively (this
+ may [5]change in future).
+ Also note that we will not discuss the very fundamentals of booting.
+ This article is fairly advanced and assumes that you know what it takes
+ to write a simple boot-loader in assembler. It is also expected that
+ you know how to write gcc inline assembly. Not everything can be done
+ in C!
+
+getting the tool-chain working
+
+.code16gcc
+
+ As we will be running in 16 bit real mode, this tells gas that the
+ assembler was generated by gcc and is intended to be run in real mode.
+ With this directive, gas automatically adds addr32 prefix wherever
+ required. For each C file which contains code to be run in real mode,
+ this directive should be present at the top of effectively generated
+ assembler code. This can be ensured by defining in a header and
+ including it before any other.
+#ifndef _CODE16GCC_H_
+#define _CODE16GCC_H_
+__asm__(".code16gcc\n");
+#endif
+
+ This is great for bootloaders as well as parts of kernel that must run
+ in real mode but are desired written in C instead of asm. In my opinion
+ C code is a lot easier to debug and maintain than asm code, at expense
+ of code size and performance at times.
+
+Special linking
+
+ As bootloader is supposed to run at physical 0x7C00, we need to tell
+ that to linker. The mbr/vbr should end with the proper boot signature
+ 0xaa55.
+ All this can be taken care of by a simple linker script.
+ENTRY(main);
+SECTIONS
+{
+ . = 0x7C00;
+ .text : AT(0x7C00)
+ {
+ _text = .;
+ *(.text);
+ _text_end = .;
+ }
+ .data :
+ {
+ _data = .;
+ *(.bss);
+ *(.bss*);
+ *(.data);
+ *(.rodata*);
+ *(COMMON)
+ _data_end = .;
+ }
+ .sig : AT(0x7DFE)
+ {
+ SHORT(0xaa55);
+ }
+ /DISCARD/ :
+ {
+ *(.note*);
+ *(.iplt*);
+ *(.igot*);
+ *(.rel*);
+ *(.comment);
+/* add any unwanted sections spewed out by your version of gcc and flags here */
+ }
+}
+
+ gcc emits elf binaries with sections, whereas a bootloader is a
+ monolithic plain binary with no sections. Conversion from elf to binary
+ can be done as follows:
+$ objcopy -O binary vbr.elf vbr.bin
+
+The code
+
+ With the toolchain set up, we can start writing our hello world
+ bootloader!
+ vbr.c (the only source file) looks something like this:
+/*
+ * A simple bootloader skeleton for x86, using gcc.
+ *
+ * Prashant Borole (boroleprashant at Google mail)
+ * */
+
+/* XXX these must be at top */
+#include "code16gcc.h"
+__asm__ ("jmpl $0, $main\n");
+
+
+#define __NOINLINE __attribute__((noinline))
+#define __REGPARM __attribute__ ((regparm(3)))
+#define __NORETURN __attribute__((noreturn))
+
+/* BIOS interrupts must be done with inline assembly */
+void __NOINLINE __REGPARM print(const char *s){
+ while(*s){
+ __asm__ __volatile__ ("int $0x10" : : "a"(0x0E00 | *s), "b"(7))
+;
+ s++;
+ }
+}
+/* and for everything else you can use C! Be it traversing the filesystem, or ve
+rifying the kernel image etc.*/
+
+void __NORETURN main(){
+ print("woo hoo!\r\n:)");
+ while(1);
+}
+
+
+ compile it as
+$ gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -I. -o vbr.o vbr.c
+$ ld -static -Tlinker.ld -nostdlib --nmagic -o vbr.elf vbr.o
+$ objcopy -O binary vbr.elf vbr.bin
+
+ and that should have created vbr.elf file (which you can use as a
+ symbols file with gdb for source level debugging the vbr with gdbstub
+ and qemu/bochs) as well as 512 byte vbr.bin. To test it, first create a
+ dummy 1.44M floppy image, and overwrite it's mbr by vbr.bin with dd.
+$ dd if=/dev/zero of=floppy.img bs=1024 count=1440
+$ dd if=vbr.bin of=floppy.img bs=1 count=512 conv=notrunc
+
+ and now we are ready to test it out :D
+$ qemu -fda floppy.img -boot a
+
+ and you should see the message!
+ Once you get to this stage, you are pretty much set with respect to the
+ tooling itself. Now you can go ahead and write code to read the
+ filesystem, search for next stage or kernel and pass control to it.
+ Here is a simple example of a floppy boot record with no filesystem,
+ and the next stage or kernel written to the floppy immediately after
+ the boot record. The next image LMA and entry are fixed in a bunch of
+ macros. It simply reads the image starting one sector after boot record
+ and passes control to it. There are many obvious holes, which I left
+ open for sake of brevity.
+/*
+ * A simple bootloader skeleton for x86, using gcc.
+ *
+ * Prashant Borole (boroleprashant at Google mail)
+ * */
+
+/* XXX these must be at top */
+#include "code16gcc.h"
+__asm__ ("jmpl $0, $main\n");
+
+
+#define __NOINLINE __attribute__((noinline))
+#define __REGPARM __attribute__ ((regparm(3)))
+#define __PACKED __attribute__((packed))
+#define __NORETURN __attribute__((noreturn))
+
+#define IMAGE_SIZE 8192
+#define BLOCK_SIZE 512
+#define IMAGE_LMA 0x8000
+#define IMAGE_ENTRY 0x800c
+
+/* BIOS interrupts must be done with inline assembly */
+void __NOINLINE __REGPARM print(const char *s){
+ while(*s){
+ __asm__ __volatile__ ("int $0x10" : : "a"(0x0E00 | *s), "b"(7))
+;
+ s++;
+ }
+}
+
+#if 0
+/* use this for the HD/USB/Optical boot sector */
+typedef struct __PACKED TAGaddress_packet_t{
+ char size;
+ char :8;
+ unsigned short blocks;
+ unsigned short buffer_offset;
+ unsigned short buffer_segment;
+ unsigned long long lba;
+ unsigned long long flat_buffer;
+}address_packet_t ;
+
+int __REGPARM lba_read(const void *buffer, unsigned int lba, unsigned short
+blocks, unsigned char bios_drive){
+ int i;
+ unsigned short failed = 0;
+ address_packet_t packet = {.size = sizeof(address_packet_t), .blocks
+= blocks, .buffer_offset = 0xFFFF, .buffer_segment = 0xFFFF, .lba = lba, .flat_b
+uffer = (unsigned long)buffer};
+ for(i = 0; i < 3; i++){
+ packet.blocks = blocks;
+ __asm__ __volatile__ (
+ "movw $0, %0\n"
+ "int $0x13\n"
+ "setcb %0\n"
+ :"=m"(failed) : "a"(0x4200), "d"(bios_drive), "S
+"(&packet) : "cc" );
+ /* do something with the error_code */
+ if(!failed)
+ break;
+ }
+ return failed;
+}
+#else
+/* use for floppy, or as a fallback */
+typedef struct {
+ unsigned char spt;
+ unsigned char numh;
+}drive_params_t;
+
+int __REGPARM __NOINLINE get_drive_params(drive_params_t *p, unsigned char
+bios_drive){
+ unsigned short failed = 0;
+ unsigned short tmp1, tmp2;
+ __asm__ __volatile__
+ (
+ "movw $0, %0\n"
+ "int $0x13\n"
+ "setcb %0\n"
+ : "=m"(failed), "=c"(tmp1), "=d"(tmp2)
+ : "a"(0x0800), "d"(bios_drive), "D"(0)
+ : "cc", "bx"
+ );
+ if(failed)
+ return failed;
+ p->spt = tmp1 & 0x3F;
+ p->numh = tmp2 >> 8;
+ return failed;
+}
+
+int __REGPARM __NOINLINE lba_read(const void *buffer, unsigned int lba, uns
+igned char blocks, unsigned char bios_drive, drive_params_t *p){
+ unsigned char c, h, s;
+ c = lba / (p->numh * p->spt);
+ unsigned short t = lba % (p->numh * p->spt);
+ h = t / p->spt;
+ s = (t % p->spt) + 1;
+ unsigned char failed = 0;
+ unsigned char num_blocks_transferred = 0;
+ __asm__ __volatile__
+ (
+ "movw $0, %0\n"
+ "int $0x13\n"
+ "setcb %0"
+ : "=m"(failed), "=a"(num_blocks_transferred)
+ : "a"(0x0200 | blocks), "c"((s << 8) | s), "d"((h << 8) | bios_driv
+e), "b"(buffer)
+ );
+ return failed || (num_blocks_transferred != blocks);
+}
+#endif
+
+/* and for everything else you can use C! Be it traversing the filesystem, or ve
+rifying the kernel image etc.*/
+
+void __NORETURN main(){
+ unsigned char bios_drive = 0;
+ __asm__ __volatile__("movb %%dl, %0" : "=r"(bios_drive)); /* the B
+IOS drive number of the device we booted from is passed in dl register */
+
+ drive_params_t p = {};
+ get_drive_params(&p, bios_drive);
+
+ void *buff = (void*)IMAGE_LMA;
+ unsigned short num_blocks = ((IMAGE_SIZE / BLOCK_SIZE) + (IMAGE_SIZE %
+BLOCK_SIZE == 0 ? 0 : 1));
+ if(lba_read(buff, 1, num_blocks, bios_drive, &p) != 0){
+ print("read error :(\r\n");
+ while(1);
+ }
+ print("Running next image...\r\n");
+ void* e = (void*)IMAGE_ENTRY;
+ __asm__ __volatile__("" : : "d"(bios_drive));
+ goto *e;
+}
+
+
+ removing __NOINLINE may result in even smaller code in this case. I had
+ it in place so that I could figure out what was happening.
+
+Concluding remarks
+
+ C in no way matches the code size and performance of hand tuned
+ size/speed optimized assembler. Also, because of an extra byte (0x66,
+ 0x67) wasted (in addr32) with almost every instruction, it is highly
+ unlikely that you can cram up the same amount of functionality as
+ assembler.
+ Global and static variables, initialized as well as uninitialized, can
+ quickly fill those precious 446 bytes. Changing them to local and
+ passing around instead may increase or decrease size; there is no thumb
+ rule and it has to be worked out on per case basis. Same goes for
+ function in-lining.
+ You also need to be extremely careful with various gcc optimization
+ flags. For example, if you have a loop in your code whose number of
+ iterations are small and deducible at compile time, and the loop body
+ is relatively small (even 20 bytes), with default -Os, gcc will unroll
+ that loop. If the loop is not unrolled (-fno-tree-loop-optimize), you
+ might be able to shave off big chunk of bytes there. Same holds true
+ for frame setups on i386 - you may want to get rid of them whenever not
+ required using -fomit-frame-pointer. Moral of the story : you need to
+ be extra careful with gcc flags as well as version update. This is not
+ much of an issue for other real mode modules of the kernel where size
+ is not of this prime importance.
+ Also, you must be very cautious with assembler warnings when compiling
+ with .code16gcc. Truncation is common. It is a very good idea to use
+ --save-temp and analyze the assembler code generated from your C and
+ inline assembly. Always take care not to mess with the C calling
+ convention in inline assembly and meticulously check and update the
+ clobber list for inline assembly doing BIOS or APM calls (but you
+ already knew it, right?).
+ It is likely that you want to switch to protected/long mode as early as
+ possible, though. Even then, I still think that maintainability wins
+ over asm's size/speed in case of a bootloader as well as the real mode
+ portions of the kernel.
+ It would be interesting if someone could try this with
+ c++/java/fortran. Please let me know if you do!
+ at [6]June 15, 2010
+ [7]Email This[8]BlogThis![9]Share to Twitter[10]Share to
+ Facebook[11]Share to Pinterest
+ Labels: [12]assembler, [13]bootloader, [14]c, [15]gas, [16]gcc,
+ [17]kernel, [18]osdev
+
+25 comments:
+
+ 1. [19]Girija[20]Tuesday, June 15, 2010 at 6:12:00 PM GMT+5:30
+ Dokyaawarun 10 foot.. kiwwa jaastach.
+ :-|
+ Reply[21]Delete
+ Replies
+ Reply
+ 2. [22]descent[23]Tuesday, December 21, 2010 at 1:10:00 PM GMT+5:30
+ Hi,
+ Thank you for your sharing.
+ in void __NOINLINE __REGPARM print(const char *s)
+ I change the print function to access pointer,
+ like this:
+ videoram[0]='H';
+ but I got the warning message:
+ /tmp/cc5qsy9l.s:33: Warning: 00000000000b8000 shortened to
+ 0000000000008000
+ Do I miss something?
+ Reply[24]Delete
+ Replies
+ Reply
+ 3. [25]descent[26]Tuesday, December 21, 2010 at 2:05:00 PM GMT+5:30
+ Hi,
+ I use gcc-3.4 to compile again.
+ I see no warning message, but in qemu,
+ I still cannot see char H.
+ videoram is static variable.
+ static unsigned char *videoram = (unsigned char *) 0xb8000;
+ Reply[27]Delete
+ Replies
+ Reply
+ 4. [28]descent[29]Tuesday, December 21, 2010 at 3:16:00 PM GMT+5:30
+ Hi,
+ I got something. In 16bit mode, the pointer is 16bit length. So
+ 0xb8000 shortened to 0x8000.
+ I write a c file and a function,
+ void put_char()
+ {
+ unsigned char *videoram = (unsigned char *) 0xb8000;
+ videoram[0]='H';
+ videoram[2]='H';
+ videoram[40]='H';
+ }
+ no include code16gcc.h, I think the pointer is 32bits length, but I
+ still can not see the H character.
+ Reply[30]Delete
+ Replies
+ Reply
+ 5. [31]Prashant[32]Tuesday, December 21, 2010 at 7:16:00 PM GMT+5:30
+ @descent: check the '--save-temps' preserved assembler version of
+ the C function.
+ This article assumes that the reader has low level programming
+ experience with x86.
+ To access the vidmem with b8000h, you have 2 options:
+ 1. write inline assembly to set es to b800h, and di to the address
+ in the real mode segment. Then write byte/word to es:di.
+ 2. Enter unreal mode. Then you can use the full 4G memory,
+ one-to-one mapped.
+ I personally would not recommend any of these methods for printing
+ - BIOS int 10h is pretty good. Remember - do not try and do
+ anything fancy in the (m/v)br; do it in the next stage instead as
+ you have pretty much unconstrained image size in later stages.
+ Reply[33]Delete
+ Replies
+ Reply
+ 6. [34]descent[35]Wednesday, December 22, 2010 at 9:41:00 AM GMT+5:30
+ Hi Prashant,
+ Thank you for your explanation.
+ Because in protected mode, I can use C,
+ and direct access 0xb8000, so I am confused.
+ real/protect mode, gcc/gas 16/32 bit also confuse me.
+ They are very complicate.
+ Reply[36]Delete
+ Replies
+ Reply
+ 7. [37]Sebastian[38]Saturday, March 12, 2011 at 6:26:00 PM GMT+5:30
+ you are a genius!
+ Reply[39]Delete
+ Replies
+ Reply
+ 8. [40]Unknown[41]Sunday, April 17, 2011 at 5:48:00 AM GMT+5:30
+ I've got that infamous runtime error...
+ bootloader.exe has encountered a problem and needs to close. We are
+ sorry for the inconvenience.
+ Reply[42]Delete
+ Replies
+ Reply
+ 9. [43]Unknown[44]Saturday, May 21, 2011 at 2:39:00 AM GMT+5:30
+ Managed to do it in C++.
+ Code is the same.
+ Linker file needs to discard eh_frame.
+ When building on x86-64 add -m32 to g++ and -melf_i386 on ld
+ command line.
+ Trying to rewrite it in a more c++-ish style.
+ My e-mail is boskovits@cogito-top.hu .
+ Reply[45]Delete
+ Replies
+ Reply
+ 10. [46]Prashant[47]Saturday, May 21, 2011 at 3:02:00 AM GMT+5:30
+ @abraker95: are you trying to run the MZ/PE image in windows? that
+ is like sinning and then spitting on the devil when in hell.
+ @boskov1985: cool man! let us know how it goes :D
+ Reply[48]Delete
+ Replies
+ Reply
+ 11. Anonymous[49]Friday, November 25, 2011 at 2:50:00 AM GMT+5:30
+ It's easier to to this without objcopy. Modern ld versions support
+ --oformat=binary , so just one line does the direct compilation
+ job.
+ gcc -g -Os -march=i686 -ffreestanding -Wall -Werror -I. -static
+ -nostdlib -Wl,-Tlinker.ld -Wl,--nmagic -Wl,--oformat=binary -o
+ loader.bin loader.c
+ Reply[50]Delete
+ Replies
+ Reply
+ 12. [51]Prashant[52]Friday, November 25, 2011 at 8:01:00 AM GMT+5:30
+ I can't verify right now whether it works, but thanks for letting
+ us know, rpfh!
+ Reply[53]Delete
+ Replies
+ Reply
+ 13. [54]descent[55]Sunday, December 4, 2011 at 9:42:00 PM GMT+5:30
+ Hi,
+ The c code uses function call, why need not set stack (ss:esp)?
+ Reply[56]Delete
+ Replies
+ Reply
+ 14. [57]Prashant[58]Tuesday, December 6, 2011 at 10:18:00 AM GMT+5:30
+ good point @decent. I guess you will need to set up the stack first
+ in main, probably in assembler.
+ Reply[59]Delete
+ Replies
+ Reply
+ 15. [60]descent[61]Saturday, December 24, 2011 at 8:02:00 PM GMT+5:30
+ I change %ss:%esp to 0x07a0:0000,
+ Is any side effect?
+ void __NORETURN main(){
+ __asm__ ("mov %cs, %ax\n");
+ __asm__ ("mov %ax, %ds\n");
+ __asm__ ("mov $0x07a0, %ax\n");
+ __asm__ ("mov %ax, %ss\n");
+ __asm__ ("mov $0, %esp\n");
+ print("woo hoo!\r\n:)");
+ while(1);
+ }
+ Reply[62]Delete
+ Replies
+ Reply
+ 16. [63]descent[64]Monday, July 30, 2012 at 8:16:00 AM GMT+5:30
+ Hi,
+ I test c bootloader in real machine, in my eeepc 904, need add some
+ code to setup stack.
+ http://descent-incoming.blogspot.tw/2012/05/x86-bootloader-hello-wo
+ rld.html
+ The article is written by Chinese, but the code, picture can give
+ some reference.
+ cppb.cpp is cpp version (compile by g++), it can work, I test it in
+ real machine(eeepc 904).
+ Reply[65]Delete
+ Replies
+ Reply
+ 17. [66]axiomfinity[67]Saturday, April 20, 2013 at 10:46:00 AM GMT+5:30
+ linker fails whats up with it..?
+ Reply[68]Delete
+ Replies
+ Reply
+ 18. [69]Prashant[70]Sunday, April 21, 2013 at 9:34:00 AM GMT+5:30
+ Fails how? Can you please elaborate?
+ Reply[71]Delete
+ Replies
+ Reply
+ 19. [72]Unknown[73]Wednesday, November 13, 2013 at 12:51:00 PM GMT+5:30
+ Thank you for detaile explanation
+ Linker failed nt sure why..ld: error: load segment overlap [0x7c00
+ -> 0x7e50] and [0x7dfe -> 0x7e00]
+ Reply[74]Delete
+ Replies
+ Reply
+ 20. [75]osdev[76]Saturday, May 31, 2014 at 1:35:00 AM GMT+5:30
+ someone here? I need to test, but...
+ "c"((s << 8) | s) <-- duplicate s in CH and CL?
+ c = lba / (p->numh * p->spt); <-- 'c' is never used...
+ maybe -> "c"((c << 8) | s)
+ Reply[77]Delete
+ Replies
+ Reply
+ 21. [78]Unknown[79]Thursday, February 5, 2015 at 8:39:00 PM GMT+5:30
+ Thank you for your nice post! I'm trying to run it on my x86-64
+ linux box, but gcc reports errors like "bad register name rax", I'm
+ a little confused by the various compiler options here, could you
+ please give me suggestions on how to compile the C source file on
+ x86-64 machines? Thanks
+ Reply[80]Delete
+ Replies
+ 1. [81]Jose Fernando Lopez Fernandez[82]Friday, January 20, 2017
+ at 2:56:00 PM GMT+5:30
+ rax is a 64 bit register. A bootloader is running in 16 bits,
+ so you cannot use rax (64 bit) or eax (32 bit). You have to
+ use ax.
+ Also, you said your computer is an x86-64. Which one is it?
+ x86 (32 bit) or 64 (64 bit)? If you have an x86, it will have
+ no idea what rax is, since it has no knowledge of 64 bit
+ registers.
+ I'm just speculating as to your problem here, though. If
+ anything here is incorrect/misguided by all means let me know,
+ I'm only a beginner too
+ [83]Delete
+ Replies
+ Reply
+ 2. [84]Jose Fernando Lopez Fernandez[85]Friday, January 20, 2017
+ at 2:57:00 PM GMT+5:30
+ @Jing Peng
+ rax is a 64 bit register. A bootloader is running in 16 bits,
+ so you cannot use rax (64 bit) or eax (32 bit). You have to
+ use ax.
+ Also, you said your computer is an x86-64. Which one is it?
+ x86 (32 bit) or 64 (64 bit)? If you have an x86, it will have
+ no idea what rax is, since it has no knowledge of 64 bit
+ registers.
+ I'm just speculating as to your problem here, though. If
+ anything here is incorrect/misguided by all means let me know,
+ I'm only a beginner too
+ [86]Delete
+ Replies
+ Reply
+ Reply
+ 22. [87]Unknown[88]Thursday, February 5, 2015 at 8:40:00 PM GMT+5:30
+ Thank you for your nice post! I'm trying to run it on my x86-64
+ linux box, but gcc reports errors like "bad register name rax", I'm
+ a little confused by the various compiler options here, could you
+ please give me suggestions on how to compile the C source file on
+ x86-64 machines? Thanks
+ Reply[89]Delete
+ Replies
+ Reply
+ 23. [90]Unknown[91]Sunday, February 7, 2016 at 8:43:00 PM GMT+5:30
+ hello i ma atif
+ Reply[92]Delete
+ Replies
+ Reply
+
+ Add comment
+ Load more...
+
+ [93]Newer Post [94]Older Post [95]Home
+ Subscribe to: [96]Post Comments (Atom)
+ * [97]Real mode in C with gcc : writing a bootloader
+ Usually the x86 boot loader is written in assembler. We will be
+ exploring the possibility of writing one in C language (as much as
+ possible)...
+ * [98]Writing kernel in Windows with Visual Studio C/C++
+ Most hobby osdev projects prefer *nix+gcc combination these days,
+ primarily because there are a bunch of nice tutorials and examples
+ availab...
+ * [99]Debugging kernel with qemu and gdb
+ Assuming that you have your (or Linux/*BSD/Solaris/Windows or any
+ other) kernel on a bootable device, you can debug the kernel and
+ also the ...
+
+Blog Archive
+
+ * [100]|> [101]2012 (1)
+ + [102]|> [103]Feb 2012 (1)
+
+ * [104]v [105]2010 (7)
+ + [106]v [107]Jun 2010 (2)
+ o [108]Cold boot attack
+ o [109]Real mode in C with gcc : writing a bootloader
+ + [110]|> [111]May 2010 (2)
+ + [112]|> [113]Apr 2010 (1)
+ + [114]|> [115]Mar 2010 (1)
+ + [116]|> [117]Feb 2010 (1)
+
+ * [118]|> [119]2009 (12)
+ + [120]|> [121]Dec 2009 (1)
+ + [122]|> [123]Nov 2009 (2)
+ + [124]|> [125]Sep 2009 (1)
+ + [126]|> [127]Aug 2009 (1)
+ + [128]|> [129]Jul 2009 (2)
+ + [130]|> [131]Feb 2009 (2)
+ + [132]|> [133]Jan 2009 (3)
+
+ * [134]|> [135]2008 (9)
+ + [136]|> [137]Nov 2008 (2)
+ + [138]|> [139]Oct 2008 (3)
+ + [140]|> [141]Aug 2008 (1)
+ + [142]|> [143]Jun 2008 (3)
+
+Labels
+
+ [144]linux [145]kernel [146]8800 [147]FreeBSD [148]gdb [149]nvidia
+ [150]osdev [151]windows 7 [152]bochs [153]boot [154]bootloader
+ [155]debug [156]dual boot [157]gas [158]gcc [159]overclock [160]pidgin
+ [161]windows [162]windows server 2008 [163]2k8 [164]3DMark [165]3DMark
+ vantage [166]820 [167]DRAM [168]Directx 10 [169]Dirext 11 [170]Java
+ [171]OpenJDK [172]OpenOffice [173]Pentium D [174]RAID [175]Sun
+ [176]UUID [177]Unicode [178]VirtualBox [179]X [180]Xorg [181]ageis
+ [182]assembler [183]authentication [184]bash [185]c [186]coolbits
+ [187]dx10 [188]fedora [189]fortune [190]gdm [191]ghostscript [192]gnome
+ [193]google [194]gs [195]gtalk [196]heat sink [197]invisible
+ [198]jabber [199]kde [200]latex [201]lvm [202]lyx [203]mount
+ [204]networked audio [205]networked sound [206]nvclock [207]oolatex
+ [208]ooolatex [209]perl [210]phonon [211]physics [212]physx [213]picasa
+ [214]plugin [215]proxy [216]pulseaudio [217]qemu [218]rsync [219]rtp
+ [220]scp [221]scp stdin [222]security [223]server [224]shell [225]squid
+ [226]ssh [227]sync [228]tar [229]udev [230]unix [231]xdm [232]xfce
+ [233]xmpp [234]xorg.conf [235]zsh
+ [236]visit counter for blogspot
+
+ Theme images by [237]5ugarless. Powered by [238]Blogger.
+
+References
+
+ Visible links:
+ 1. http://dc0d32.blogspot.com/feeds/posts/default
+ 2. http://dc0d32.blogspot.com/feeds/posts/default?alt=rss
+ 3. http://dc0d32.blogspot.com/feeds/6370208028763486595/comments/default
+ 4. http://dc0d32.blogspot.com/
+ 5. http://gcc.gnu.org/ml/gcc/1999-07n/msg00483.html
+ 6. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html
+ 7. https://www.blogger.com/share-post.g?blogID=35813921&postID=6370208028763486595&target=email
+ 8. https://www.blogger.com/share-post.g?blogID=35813921&postID=6370208028763486595&target=blog
+ 9. https://www.blogger.com/share-post.g?blogID=35813921&postID=6370208028763486595&target=twitter
+ 10. https://www.blogger.com/share-post.g?blogID=35813921&postID=6370208028763486595&target=facebook
+ 11. https://www.blogger.com/share-post.g?blogID=35813921&postID=6370208028763486595&target=pinterest
+ 12. http://dc0d32.blogspot.com/search/label/assembler
+ 13. http://dc0d32.blogspot.com/search/label/bootloader
+ 14. http://dc0d32.blogspot.com/search/label/c
+ 15. http://dc0d32.blogspot.com/search/label/gas
+ 16. http://dc0d32.blogspot.com/search/label/gcc
+ 17. http://dc0d32.blogspot.com/search/label/kernel
+ 18. http://dc0d32.blogspot.com/search/label/osdev
+ 19. https://www.blogger.com/profile/06904019980664523275
+ 20. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1276605767623#c7537756629084768590
+ 21. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=7537756629084768590
+ 22. https://www.blogger.com/profile/17992312956580227764
+ 23. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1292917257855#c7916645211913421716
+ 24. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=7916645211913421716
+ 25. https://www.blogger.com/profile/17992312956580227764
+ 26. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1292920505936#c6914976194912758237
+ 27. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=6914976194912758237
+ 28. https://www.blogger.com/profile/17992312956580227764
+ 29. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1292924802000#c3509490007866551116
+ 30. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=3509490007866551116
+ 31. https://www.blogger.com/profile/15716533043357974705
+ 32. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1292939196737#c8552773997968662641
+ 33. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=8552773997968662641
+ 34. https://www.blogger.com/profile/17992312956580227764
+ 35. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1292991102048#c3691472389082213083
+ 36. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=3691472389082213083
+ 37. https://www.blogger.com/profile/04546527990311411722
+ 38. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1299934567958#c8861407369344586215
+ 39. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=8861407369344586215
+ 40. https://www.blogger.com/profile/13931402888317484377
+ 41. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1302999537204#c1796379189090357880
+ 42. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=1796379189090357880
+ 43. https://www.blogger.com/profile/10664008816666619973
+ 44. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1305925792707#c309698377277262219
+ 45. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=309698377277262219
+ 46. https://www.blogger.com/profile/15716533043357974705
+ 47. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1305927124224#c7619831240140737017
+ 48. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=7619831240140737017
+ 49. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1322169605658#c1693276418345545837
+ 50. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=1693276418345545837
+ 51. https://www.blogger.com/profile/15716533043357974705
+ 52. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1322188282688#c6259496576598783959
+ 53. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=6259496576598783959
+ 54. https://www.blogger.com/profile/17992312956580227764
+ 55. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1323015134989#c3945832952459710949
+ 56. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=3945832952459710949
+ 57. https://www.blogger.com/profile/15716533043357974705
+ 58. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1323146939454#c2066813635755540091
+ 59. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=2066813635755540091
+ 60. https://www.blogger.com/profile/17992312956580227764
+ 61. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1324737140263#c7908397772486068687
+ 62. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=7908397772486068687
+ 63. https://www.blogger.com/profile/17992312956580227764
+ 64. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1343616406999#c8117194716929362278
+ 65. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=8117194716929362278
+ 66. https://www.blogger.com/profile/00410755183408310829
+ 67. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1366435009449#c1258130037332531147
+ 68. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=1258130037332531147
+ 69. https://www.blogger.com/profile/15716533043357974705
+ 70. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1366517094365#c8123329091843779139
+ 71. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=8123329091843779139
+ 72. https://www.blogger.com/profile/17234059656421576642
+ 73. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1384327289704#c4134298820836763034
+ 74. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=4134298820836763034
+ 75. https://www.blogger.com/profile/16683260877229099988
+ 76. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1401480336214#c455729903293178418
+ 77. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=455729903293178418
+ 78. https://www.blogger.com/profile/07765096042053323038
+ 79. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1423148995473#c7126019925062815723
+ 80. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=7126019925062815723
+ 81. https://www.blogger.com/profile/01833111909520604012
+ 82. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1484904386672#c7038618115198897417
+ 83. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=7038618115198897417
+ 84. https://www.blogger.com/profile/01833111909520604012
+ 85. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1484904424918#c1284220459583274955
+ 86. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=1284220459583274955
+ 87. https://www.blogger.com/profile/07765096042053323038
+ 88. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1423149010339#c2287827836063649127
+ 89. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=2287827836063649127
+ 90. https://www.blogger.com/profile/17596900636592437710
+ 91. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html?showComment=1454858010555#c4198004625201390279
+ 92. https://www.blogger.com/delete-comment.g?blogID=35813921&postID=4198004625201390279
+ 93. http://dc0d32.blogspot.com/2010/06/cold-boot-attack.html
+ 94. http://dc0d32.blogspot.com/2010/05/how-not-to-look-like-fool-on-facebook.html
+ 95. http://dc0d32.blogspot.com/
+ 96. http://dc0d32.blogspot.com/feeds/6370208028763486595/comments/default
+ 97. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html
+ 98. http://dc0d32.blogspot.com/2012/02/writing-kernel-in-windows-with-visual.html
+ 99. http://dc0d32.blogspot.com/2010/03/debugging-kernel-with-qemu-and-gdb.html
+ 100. javascript:void(0)
+ 101. http://dc0d32.blogspot.com/2012/
+ 102. javascript:void(0)
+ 103. http://dc0d32.blogspot.com/2012/02/
+ 104. javascript:void(0)
+ 105. http://dc0d32.blogspot.com/2010/
+ 106. javascript:void(0)
+ 107. http://dc0d32.blogspot.com/2010/06/
+ 108. http://dc0d32.blogspot.com/2010/06/cold-boot-attack.html
+ 109. http://dc0d32.blogspot.com/2010/06/real-mode-in-c-with-gcc-writing.html
+ 110. javascript:void(0)
+ 111. http://dc0d32.blogspot.com/2010/05/
+ 112. javascript:void(0)
+ 113. http://dc0d32.blogspot.com/2010/04/
+ 114. javascript:void(0)
+ 115. http://dc0d32.blogspot.com/2010/03/
+ 116. javascript:void(0)
+ 117. http://dc0d32.blogspot.com/2010/02/
+ 118. javascript:void(0)
+ 119. http://dc0d32.blogspot.com/2009/
+ 120. javascript:void(0)
+ 121. http://dc0d32.blogspot.com/2009/12/
+ 122. javascript:void(0)
+ 123. http://dc0d32.blogspot.com/2009/11/
+ 124. javascript:void(0)
+ 125. http://dc0d32.blogspot.com/2009/09/
+ 126. javascript:void(0)
+ 127. http://dc0d32.blogspot.com/2009/08/
+ 128. javascript:void(0)
+ 129. http://dc0d32.blogspot.com/2009/07/
+ 130. javascript:void(0)
+ 131. http://dc0d32.blogspot.com/2009/02/
+ 132. javascript:void(0)
+ 133. http://dc0d32.blogspot.com/2009/01/
+ 134. javascript:void(0)
+ 135. http://dc0d32.blogspot.com/2008/
+ 136. javascript:void(0)
+ 137. http://dc0d32.blogspot.com/2008/11/
+ 138. javascript:void(0)
+ 139. http://dc0d32.blogspot.com/2008/10/
+ 140. javascript:void(0)
+ 141. http://dc0d32.blogspot.com/2008/08/
+ 142. javascript:void(0)
+ 143. http://dc0d32.blogspot.com/2008/06/
+ 144. http://dc0d32.blogspot.com/search/label/linux
+ 145. http://dc0d32.blogspot.com/search/label/kernel
+ 146. http://dc0d32.blogspot.com/search/label/8800
+ 147. http://dc0d32.blogspot.com/search/label/FreeBSD
+ 148. http://dc0d32.blogspot.com/search/label/gdb
+ 149. http://dc0d32.blogspot.com/search/label/nvidia
+ 150. http://dc0d32.blogspot.com/search/label/osdev
+ 151. http://dc0d32.blogspot.com/search/label/windows%207
+ 152. http://dc0d32.blogspot.com/search/label/bochs
+ 153. http://dc0d32.blogspot.com/search/label/boot
+ 154. http://dc0d32.blogspot.com/search/label/bootloader
+ 155. http://dc0d32.blogspot.com/search/label/debug
+ 156. http://dc0d32.blogspot.com/search/label/dual%20boot
+ 157. http://dc0d32.blogspot.com/search/label/gas
+ 158. http://dc0d32.blogspot.com/search/label/gcc
+ 159. http://dc0d32.blogspot.com/search/label/overclock
+ 160. http://dc0d32.blogspot.com/search/label/pidgin
+ 161. http://dc0d32.blogspot.com/search/label/windows
+ 162. http://dc0d32.blogspot.com/search/label/windows%20server%202008
+ 163. http://dc0d32.blogspot.com/search/label/2k8
+ 164. http://dc0d32.blogspot.com/search/label/3DMark
+ 165. http://dc0d32.blogspot.com/search/label/3DMark%20vantage
+ 166. http://dc0d32.blogspot.com/search/label/820
+ 167. http://dc0d32.blogspot.com/search/label/DRAM
+ 168. http://dc0d32.blogspot.com/search/label/Directx%2010
+ 169. http://dc0d32.blogspot.com/search/label/Dirext%2011
+ 170. http://dc0d32.blogspot.com/search/label/Java
+ 171. http://dc0d32.blogspot.com/search/label/OpenJDK
+ 172. http://dc0d32.blogspot.com/search/label/OpenOffice
+ 173. http://dc0d32.blogspot.com/search/label/Pentium%20D
+ 174. http://dc0d32.blogspot.com/search/label/RAID
+ 175. http://dc0d32.blogspot.com/search/label/Sun
+ 176. http://dc0d32.blogspot.com/search/label/UUID
+ 177. http://dc0d32.blogspot.com/search/label/Unicode
+ 178. http://dc0d32.blogspot.com/search/label/VirtualBox
+ 179. http://dc0d32.blogspot.com/search/label/X
+ 180. http://dc0d32.blogspot.com/search/label/Xorg
+ 181. http://dc0d32.blogspot.com/search/label/ageis
+ 182. http://dc0d32.blogspot.com/search/label/assembler
+ 183. http://dc0d32.blogspot.com/search/label/authentication
+ 184. http://dc0d32.blogspot.com/search/label/bash
+ 185. http://dc0d32.blogspot.com/search/label/c
+ 186. http://dc0d32.blogspot.com/search/label/coolbits
+ 187. http://dc0d32.blogspot.com/search/label/dx10
+ 188. http://dc0d32.blogspot.com/search/label/fedora
+ 189. http://dc0d32.blogspot.com/search/label/fortune
+ 190. http://dc0d32.blogspot.com/search/label/gdm
+ 191. http://dc0d32.blogspot.com/search/label/ghostscript
+ 192. http://dc0d32.blogspot.com/search/label/gnome
+ 193. http://dc0d32.blogspot.com/search/label/google
+ 194. http://dc0d32.blogspot.com/search/label/gs
+ 195. http://dc0d32.blogspot.com/search/label/gtalk
+ 196. http://dc0d32.blogspot.com/search/label/heat%20sink
+ 197. http://dc0d32.blogspot.com/search/label/invisible
+ 198. http://dc0d32.blogspot.com/search/label/jabber
+ 199. http://dc0d32.blogspot.com/search/label/kde
+ 200. http://dc0d32.blogspot.com/search/label/latex
+ 201. http://dc0d32.blogspot.com/search/label/lvm
+ 202. http://dc0d32.blogspot.com/search/label/lyx
+ 203. http://dc0d32.blogspot.com/search/label/mount
+ 204. http://dc0d32.blogspot.com/search/label/networked%20audio
+ 205. http://dc0d32.blogspot.com/search/label/networked%20sound
+ 206. http://dc0d32.blogspot.com/search/label/nvclock
+ 207. http://dc0d32.blogspot.com/search/label/oolatex
+ 208. http://dc0d32.blogspot.com/search/label/ooolatex
+ 209. http://dc0d32.blogspot.com/search/label/perl
+ 210. http://dc0d32.blogspot.com/search/label/phonon
+ 211. http://dc0d32.blogspot.com/search/label/physics
+ 212. http://dc0d32.blogspot.com/search/label/physx
+ 213. http://dc0d32.blogspot.com/search/label/picasa
+ 214. http://dc0d32.blogspot.com/search/label/plugin
+ 215. http://dc0d32.blogspot.com/search/label/proxy
+ 216. http://dc0d32.blogspot.com/search/label/pulseaudio
+ 217. http://dc0d32.blogspot.com/search/label/qemu
+ 218. http://dc0d32.blogspot.com/search/label/rsync
+ 219. http://dc0d32.blogspot.com/search/label/rtp
+ 220. http://dc0d32.blogspot.com/search/label/scp
+ 221. http://dc0d32.blogspot.com/search/label/scp%20stdin
+ 222. http://dc0d32.blogspot.com/search/label/security
+ 223. http://dc0d32.blogspot.com/search/label/server
+ 224. http://dc0d32.blogspot.com/search/label/shell
+ 225. http://dc0d32.blogspot.com/search/label/squid
+ 226. http://dc0d32.blogspot.com/search/label/ssh
+ 227. http://dc0d32.blogspot.com/search/label/sync
+ 228. http://dc0d32.blogspot.com/search/label/tar
+ 229. http://dc0d32.blogspot.com/search/label/udev
+ 230. http://dc0d32.blogspot.com/search/label/unix
+ 231. http://dc0d32.blogspot.com/search/label/xdm
+ 232. http://dc0d32.blogspot.com/search/label/xfce
+ 233. http://dc0d32.blogspot.com/search/label/xmpp
+ 234. http://dc0d32.blogspot.com/search/label/xorg.conf
+ 235. http://dc0d32.blogspot.com/search/label/zsh
+ 236. http://www.statcounter.com/blogger/
+ 237. http://www.istockphoto.com/portfolio/5ugarless?platform=blogger
+ 238. https://www.blogger.com/
+
+ Hidden links:
+ 240. https://www.blogger.com/post-edit.g?blogID=35813921&postID=6370208028763486595&from=pencil
+ 241. https://www.blogger.com/comment/frame/35813921?po=6370208028763486595&hl=en