Assembling a boot sector using Cygwin GAS - feasible or not?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Schol-R-LEA

Assembling a boot sector using Cygwin GAS - feasible or not?

Post by Schol-R-LEA »

The other day, I added a link in a FAQ page to the GAS End User's Help Project web page, and while reading through the page, I noticed that the message board had several references to writing a boot sector in GAS. Apparently, this is, or was, considered a major topic of the group. However, the boot sectors listed were not, generally speaking, very good.

Out of curiosity, I decided to try converted a recent version of my own VERBUM bootloader demo to AT&T syntax; I figured I needed the practice at GAS assembly anyway, and I hoped I could provide it to them to help them out. The code conversion was actually fairly simple; and in fact much of it was done with a few search and replace passes. Once I started trying to assemble it, I did learn a few interesting things. First, the AT&T equivalents of certain NASM idioms did not work as I expected. For example, you cannot use

[tt]spacing: .skip (0x1fe - (. - boot_offset)[/tt]

to space the end code (.space cannot use a varible value like the '.' directive); however, I found that

[tt] .= 0x01fe[/tt]

did the job nicely, resetting the origin to the last two bytes of the sector. I also found that macros did not work quite as I expected; I ended up hand-inserting the code that I'd used macros for in NASM, figuring to get back to them later.

Interestingly, the GAS code assembled to a larger image than the NASM code did; I had to trim the message strings in order to get it to fit within the size constraints if the second '.=' statement. Looking into it furher, I found that the NASM code was larger than I expected; filling up almost the whole available space. This was particualrly disturbing since I was planning on re-writing VERBUM to work as a FAT12 loader, and had just added the BPB in order to support it. I will have to look into the code to see why it is so inefficent.

Having done this, I was able to assemble the code into a 35k PE object file. Since I would need a raw binary, my next step was to try using objcopy to strip the relocation information. In order to do that, I would have to link it and to produce a complete PE executable first. Since I expected that I would need to edit the source file eventually, I wrote a makefile for it:

Code: Select all

ASM = D:\Dev-Cpp\bin\as.exe
LINKER = D:\Dev-Cpp\bin\ld.exe
STRIP = D:\Dev-Cpp\bin\objcopy.exe
STRIPARGS =  -j .text -S -O binary

SRC = verbum-0_2_0.s

verbum: verbum.bin
???$(STRIP) $(STRIPARGS) verbum.bin verbum 

verbum.bin: verbum.o
???$(LINKER) -Ttext 7c00 verbum.o -o verbum.bin

verbum.o: $(SRC)
???$(ASM) $(SRC) -o verbum.o
As you can see, the idea was to remove everything texcept the .text section. However (after some fiddling with the linker arguments to get it to work correctly), the result was a 32K file in an inderterminate format, which needless to say, did not work when I tried inserting it into a test boot image for BOCHS.

Does anyone else have any experience in using gas to produce raw binaries? I am doing something wrong in the assemlber call? I the linker call? in the objcopy call? Is the problem related to the fact that Cygwin produces PE files instead of ELF?

This isn't a critical issue, as I will probably go back to using NASM for the near future. I would, however, be interested in the answers. The text of the assembler code file is attached.
Curufir

Re:Assembling a boot sector using Cygwin GAS - feasible or n

Post by Curufir »

Here's my makefile (Using GAS of course).

This isn't using the Cygwin GAS, but I doubt the flags are any different.

Code: Select all

SOURCES = stage0.S stage0.h

OBJS = stage0.o

CFLAGS = -Wall -fno-builtin -nostdinc -O -I. -c

LDFLAGS = -nostdblib -o stage0.bin --oformat binary

stage0.bin: $(OBJS)
   $(LD) $(LDFLAGS) stage0.o;

stage0.o: $(SOURCES)
   $(CC) $(CFLAGS) stage0.S
Can't see why ld on cygwin would be missing the binary format.

***

Update:

Apparently I was wrong, couldn't be more wrong in fact. Can't get LD to use the --oformat flag properly under Cygwin so you're gonna have to play with objcopy for plain binary.
jinksys

Re:Assembling a boot sector using Cygwin GAS - feasible or n

Post by jinksys »

Im currently tinkering with bootsectors right now, and
I use:

.org   510,0
.byte   0x55,0xAA

to insert the boot signature into the binary. I assembly my code with...

as bootsect.s -o bootsect.o
ld --oformat binary -Ttext 0x0 bootsect.o -o bootsect

Hope this helps...
Post Reply