strange error in MBR code for UFD

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
SolidSnake
Posts: 10
Joined: Thu Jun 28, 2007 6:36 am

strange error in MBR code for UFD

Post by SolidSnake »

I'm trying to write simple "Hello world" code on MBR/sector 1 in my USB Flash Drive (UFD). I'm using TASM 5.0 and then manually, extracting the code portion from the *.EXE and pasting it into sector 1 of UFD using disk editor.
But I got strange results. The screen showing something like "Hel@". The same code, if written under harddisk bootarea (first sector of partition), can run properly.
Strangely, everything is okay if I'm not using Jump or JXXX in my code.
Currently, I'm using option "USB-ZIP" as my first boot device. "USB-HDD" and others won't work. Is there something I need to do to boot from UFD properly?
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Post by hailstorm »

Can you post your bootcode? That gives us more information... :D
SolidSnake
Posts: 10
Joined: Thu Jun 28, 2007 6:36 am

Post by SolidSnake »

It was something like:

Code: Select all

     LEA   SI, HELLO
     MOV  AH, 0EH    
L1:
     LODSB
     OR    AL, AL
     JZ     HANG
     INT   10H
     JMP   L1

HANG:  JMP HANG

HELLO  DB  'Hello Words!',0
When I boot my PC, it just show something like: "Hel@" and then hang (sometimes I even can't press Ctrl+Alt+Del, but I don't CLI).
The same code run properly if written under my harddisk partition. I don't know what is happening here...[/code]
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Post by hailstorm »

Hmmm. Ok, your code is fine, but I have the feeling that you don't know what is happening before your code starts.
Please keep in mind that the bios puts your code at 0x7c00 in memory, with al segment registers set to 0. So, before you can use a string in assembly while booting, you must do the following:
Compile your code using org 0x7c00.
Or
Initialize es and / or ds to 0x7c0.

Also don't forget to put the number 0x55aa at byte 510 in your code.

I hope this helps, if it doesn't, I am sure a lot of other people know how to help you with your problem.

Greetz.
SolidSnake
Posts: 10
Joined: Thu Jun 28, 2007 6:36 am

Post by SolidSnake »

Oops.. I forget to include the initilization here.. I have wrote the stack initialization (set SS to 0 and SP to 7C00H) and set DS to 0 also include ORG 7C00H..

But, coz I'm new and using TASM 5.0, after compile and linking, I manually extract the machine code from the DOS EXE format. I remember it was starting at offset 7E00H.. Is it okay? Anyway, I really like to know if I have easier way to do that in TASM 5.0 dan TLINK 5.1. May be there's some arguments to pass in command prompt?

Thanks for the help, bro.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
SolidSnake wrote:Oops.. I forget to include the initilization here.. I have wrote the stack initialization (set SS to 0 and SP to 7C00H) and set DS to 0 also include ORG 7C00H..

But, coz I'm new and using TASM 5.0, after compile and linking, I manually extract the machine code from the DOS EXE format. I remember it was starting at offset 7E00H.. Is it okay? Anyway, I really like to know if I have easier way to do that in TASM 5.0 dan TLINK 5.1. May be there's some arguments to pass in command prompt?
This makes me wonder if your initialization code started with something like "jmp 0x0000:start", which didn't work because TASM encoded it as "jmp 0x0000:0x7E??".

Anyway, TASM is "unmaintained" (or as some people call it, abandonware) - TASM 5.0 is at least 10 years old, and AFAIK doesn't support any of the new instructions (3DNOW, MMX, SSE, etc). I'd also assume that if you ever want to port it to your OS you'll have trouble.

There's plenty of good free open source assemblers (NASM, YASM, FASM, etc). It's probably better to switch assemblers now, instead of trying to figure out how to stop TASM from generating DOS executables (and then switching to a more modern assembler later anyway)... ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Post by hailstorm »

The value 7e00h doesn't supprise me at all. You see, tasm compiles an exe and this is DOS executable. These executables always contain a header 512 bytes, which is ofcourse 0200h.
If I were you, I wouldn't compile the executable as an EXE, but as a com-file.
Or even better. Start your program by initializing ds, es and ss to 07C0H. Then, let the assembler know you are starting at address 0, by using ORG 0 right after segment declaration, or .CODE, whatever you are using.

Code: Select all

NEW_SEGMENT     =       07C0H
STACK_POINTER   =       03FEH
MAGIC1          =       02004H
MAGIC2          =       0502H

jmpfa   MACRO seg, ofs
          db 0eah
          dw ofs, seg
        ENDM

_TEXT SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:_TEXT, DS:_TEXT
jmp		start
	db	'Hailos01'
	dw	512
	db	1
	dw	1
	db	2
	dw	224
	dw	0
	db	0f0h
	dw	2880
	
start:
  mov   ax, NEW_SEGMENT
  mov   ds, ax
  mov   es, ax
  cli                           ; Disable interrupts, very important!
  mov   ss, ax                  ; Set the stacksegment
  mov   sp, STACK_POINTER       ; Set the stackpointer
  sti                           ; Enable interrupt flag.

NEW_OFS        =       offset re_enter
  jmpfa NEW_SEGMENT, NEW_OFS
re_enter:
  blah and code so on.
Although TASM is abandonware, for bootsector programming it is an excelent assembler.
SolidSnake
Posts: 10
Joined: Thu Jun 28, 2007 6:36 am

Post by SolidSnake »

Oh, i see.. Thanks all for the info.. I'm still new in OS programming, and all I know is some programming in TASM and C/C++.. I can't compile them into COM coz looks like TLINK want me to use ORG 100H to link properly. Maybe I really must learn new assembler syntax and switch to newer assembler..

But right now, I don't use UFD as boot device again. I though it will be easier if I'm using UFD. Now, I'm using one of my harddisk partitions to test my "hello world" OS. And the boot code run properly.. And I'm confused again.. I'm using Visual C++ 2005 to generate the code, and I don't know what should I do.. (when I'm using DOS EXE, I just extract the code starting from 7E00H).. But in PE format, there are RVA, sections, and a lot.. Is it possible to use Visual C++? Or I must download GCC and DD (I live in slow internet connection country)?
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Post by hailstorm »

I would suggest you get gcc somehow (maybe you have a friend who has broadband?). Using gcc you can create executables with coff header format. Though I know PE and coff aren't that much different from eachother, coff is much better explained I guess.
I also think it is possible to generate MZ executables using VC++ 2005, but you have to dig into your project's options...

About tlink; I guess you could use org 100h, tlink should relocate all references to variables automatically, that is, adding 100h to references.

Good luck!
SolidSnake
Posts: 10
Joined: Thu Jun 28, 2007 6:36 am

Post by SolidSnake »

Thanks for the suggesting..

I still don't understand about the use of PE or COFF here.. I have write boot code in sector 0 of partition, and the code will read 6 sector starting at sector 1 to memory 0000:8000H. And then, I jump far using RETF to 0000:8000H. What should I do next?

It's that I should put my kernel code starting at sector 2? But when I'm using Visual C++ and generating PE EXE, I don't know if I could just put the ".TEXT" section and ".DATA" section into sector 2. What happen if I use COFF?
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Post by hailstorm »

The reason for these headers in executables is for the kernel to know where the text, data, bss and other sections can be found. Also symbol and relocation data can be found in these headers. That's also the reason why it is hard to understand how to read the header of an executable.

Althought I bet it is possible, it is hard to code logic in a bootsector that reads an executable and that examines the header where it should load the sections in memory. Therefore OS developers program a second stage bootloader which is somewhat bigger in size, but also can do a little more.

My suggestion is that you try to program a bootsector that supports fat. So you can load a secondstage bootloader that does the rest. There is enough information to be found on these subjects, but it is somewhat hard to grasp...

I wish you luck.
SolidSnake
Posts: 10
Joined: Thu Jun 28, 2007 6:36 am

Post by SolidSnake »

Thanks.. I understand now... It seems that boot loader do something like program loader.. So, maybe I can program the kernel in PE format, and then load the PE file into memory according the BaseMemory field, and then jump into InitialProgramEntry, I hope that will work..
Thanks again..
User avatar
XCHG
Member
Member
Posts: 416
Joined: Sat Nov 25, 2006 3:55 am
Location: Wisconsin
Contact:

Post by XCHG »

Here are some food for thought:

• BIOS does NOT load the MBR into 0x0000:0x7C0, it loads it into 0x0000:0x7C00. Note the extra zero to the right of the latter number. The former is 1984 in decimal but the latter is 31744.

• Your best bet for coding a bootstrap is to use NASM that is freely available in the Internet.

• When using NASM, assemble your bootstrap into a flat binary file using the "-f bin" switch.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

You could assemble it as a mz EXE and load it with bootprog, a boot load that can load mz exe or com files: http://alexfru.chat.ru/epm.html#bootprog
SolidSnake
Posts: 10
Joined: Thu Jun 28, 2007 6:36 am

Post by SolidSnake »

Thanks for the link, I'm downloading the resources from there right now.. It should give me more information about OS implementation..

And thanks, XCHG for the food.. I'll try NASM too..

I've tried to call the PE code after my boot sector code, but I just realized some code in the PE file use something like 32-bit CALL (intrasegment call, but not with 2 bytes displacement, but 4 bytes displacement).. I think in real mode, the CPU will just use the 2 first bytes. It seems that I must switch to protected mode first before calling the PE file, and still doing a lot in assembler rather in C. Maybe that's what GRUB doing in the os tutorial I read (I can't follow the tutorial coz I don't have GRUB, so I decide to write the bootcode myself, but I realize it's too hard).
Post Reply